2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* OSPF Link State Advertisement
|
|
|
|
* Copyright (C) 1999, 2000 Toshiaki Takada
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2017-01-17 22:05:56 +01:00
|
|
|
#include "monotime.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "linklist.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "stream.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "thread.h"
|
|
|
|
#include "hash.h"
|
|
|
|
#include "sockunion.h" /* for inet_aton() */
|
2008-08-13 20:09:10 +02:00
|
|
|
#include "checksum.h"
|
2020-04-17 15:35:15 +02:00
|
|
|
#include "network.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include "ospfd/ospfd.h"
|
|
|
|
#include "ospfd/ospf_interface.h"
|
|
|
|
#include "ospfd/ospf_ism.h"
|
|
|
|
#include "ospfd/ospf_asbr.h"
|
|
|
|
#include "ospfd/ospf_lsa.h"
|
|
|
|
#include "ospfd/ospf_lsdb.h"
|
|
|
|
#include "ospfd/ospf_neighbor.h"
|
|
|
|
#include "ospfd/ospf_nsm.h"
|
|
|
|
#include "ospfd/ospf_flood.h"
|
|
|
|
#include "ospfd/ospf_packet.h"
|
|
|
|
#include "ospfd/ospf_spf.h"
|
|
|
|
#include "ospfd/ospf_dump.h"
|
|
|
|
#include "ospfd/ospf_route.h"
|
|
|
|
#include "ospfd/ospf_ase.h"
|
|
|
|
#include "ospfd/ospf_zebra.h"
|
2011-12-22 15:07:15 +01:00
|
|
|
#include "ospfd/ospf_abr.h"
|
2018-08-21 03:18:05 +02:00
|
|
|
#include "ospfd/ospf_errors.h"
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2023-03-17 10:17:39 +01:00
|
|
|
static struct ospf_lsa *ospf_handle_summarylsa_lsId_chg(struct ospf_area *area,
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct prefix_ipv4 *p,
|
|
|
|
uint8_t type,
|
|
|
|
uint32_t metric,
|
|
|
|
struct in_addr old_id);
|
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_summary_lsa_prepare_and_flood(struct prefix_ipv4 *p, uint32_t metric,
|
|
|
|
struct ospf_area *area, struct in_addr id);
|
|
|
|
static struct ospf_lsa *ospf_summary_lsa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa);
|
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_asbr_summary_lsa_prepare_and_flood(struct prefix_ipv4 *p, uint32_t metric,
|
|
|
|
struct ospf_area *area,
|
|
|
|
struct in_addr id);
|
|
|
|
static struct ospf_lsa *ospf_summary_asbr_lsa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa);
|
|
|
|
static struct ospf_lsa *ospf_handle_exnl_lsa_lsId_chg(struct ospf *ospf,
|
|
|
|
struct external_info *ei,
|
|
|
|
struct in_addr id);
|
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_exnl_lsa_prepare_and_flood(struct ospf *ospf, struct external_info *ei,
|
|
|
|
struct in_addr id);
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t get_metric(uint8_t *metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t m;
|
2002-12-13 21:15:29 +01:00
|
|
|
m = metric[0];
|
|
|
|
m = (m << 8) + metric[1];
|
|
|
|
m = (m << 8) + metric[2];
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2022-11-21 13:50:16 +01:00
|
|
|
/** @brief The Function checks self generated DoNotAge.
|
|
|
|
* @param lsa pointer.
|
|
|
|
* @return true or false.
|
|
|
|
*/
|
|
|
|
bool ospf_check_dna_lsa(const struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
return ((IS_LSA_SELF(lsa) && CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE))
|
|
|
|
? true
|
|
|
|
: false);
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2015-05-20 03:04:07 +02:00
|
|
|
struct timeval int2tv(int a)
|
|
|
|
{
|
|
|
|
struct timeval ret;
|
|
|
|
|
2015-07-27 07:56:25 +02:00
|
|
|
ret.tv_sec = a;
|
|
|
|
ret.tv_usec = 0;
|
2015-05-20 03:04:07 +02:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
struct timeval msec2tv(int a)
|
|
|
|
{
|
|
|
|
struct timeval ret;
|
|
|
|
|
2015-07-27 07:56:25 +02:00
|
|
|
ret.tv_sec = a / 1000;
|
|
|
|
ret.tv_usec = (a % 1000) * 1000;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-01-17 22:05:56 +01:00
|
|
|
return ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int ospf_lsa_refresh_delay(struct ospf_lsa *lsa)
|
|
|
|
{
|
2017-01-17 22:05:56 +01:00
|
|
|
struct timeval delta;
|
2002-12-13 21:15:29 +01:00
|
|
|
int delay = 0;
|
|
|
|
|
2017-01-17 22:05:56 +01:00
|
|
|
if (monotime_since(&lsa->tv_orig, &delta)
|
|
|
|
< OSPF_MIN_LS_INTERVAL * 1000LL) {
|
|
|
|
struct timeval minv = msec2tv(OSPF_MIN_LS_INTERVAL);
|
|
|
|
timersub(&minv, &delta, &minv);
|
|
|
|
|
|
|
|
/* TBD: remove padding to full sec, return timeval instead */
|
|
|
|
delay = minv.tv_sec + !!minv.tv_usec;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Refresh timer delay %d seconds",
|
|
|
|
lsa->data->type, &lsa->data->id,
|
2002-12-13 21:15:29 +01:00
|
|
|
delay);
|
|
|
|
|
|
|
|
assert(delay > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return delay;
|
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
int get_age(struct ospf_lsa *lsa)
|
|
|
|
{
|
2017-01-17 22:05:56 +01:00
|
|
|
struct timeval rel;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2022-11-21 13:50:16 +01:00
|
|
|
/* As per rfc4136, the self-originated LSAs in their
|
|
|
|
* own database keep aging, however rfc doesn't tell
|
|
|
|
* till how long the LSA should be aged, as of now
|
|
|
|
* we are capping it for OSPF_LSA_MAXAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* If LSA is marked as donotage */
|
|
|
|
if (CHECK_FLAG(lsa->data->ls_age, DO_NOT_AGE) && !IS_LSA_SELF(lsa))
|
|
|
|
return ntohs(lsa->data->ls_age);
|
|
|
|
|
2017-01-17 22:05:56 +01:00
|
|
|
monotime_since(&lsa->tv_recv, &rel);
|
|
|
|
return ntohs(lsa->data->ls_age) + rel.tv_sec;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Fletcher Checksum -- Refer to RFC1008. */
|
|
|
|
|
2008-08-13 20:09:10 +02:00
|
|
|
/* All the offsets are zero-based. The offsets in the RFC1008 are
|
|
|
|
one-based. */
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t ospf_lsa_checksum(struct lsa_header *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-04-08 07:57:15 +02:00
|
|
|
uint8_t *buffer = &lsa->options;
|
2018-03-27 21:13:34 +02:00
|
|
|
int options_offset = buffer - (uint8_t *)&lsa->ls_age; /* should be 2 */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-13 20:09:10 +02:00
|
|
|
/* Skip the AGE field */
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t len = ntohs(lsa->length) - options_offset;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-13 20:09:10 +02:00
|
|
|
/* Checksum offset starts from "options" field, not the beginning of the
|
|
|
|
lsa_header struct. The offset is 14, rather than 16. */
|
2018-03-27 21:13:34 +02:00
|
|
|
int checksum_offset = (uint8_t *)&lsa->checksum - buffer;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2008-08-13 20:09:10 +02:00
|
|
|
return fletcher_checksum(buffer, len, checksum_offset);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
lib: improve fletcher checksum validation
OVERVIEW
The checksum used in OSPF (rfc2328) is specified in rc905 annex B. There is an
sample implementation in rfc1008 which forms the basis of the quagga
implementation. This algorithm works perfectly when generating a checksum;
however, validation is a bit problematic.
The following LSA (generated by a non-quagga implementation) is received by
quagga and marked with an invalid checksum; however, it passes both the rfc905
and rfc1008 validation checks.
static uint8_t lsa_10_121_233_29[] = {
0x0e, 0x10, 0x02, 0x03,
0x09, 0x00, 0x35, 0x40,
0x0a, 0x79, 0xe9, 0x1d,
0x80, 0x00, 0x00, 0x03,
0x00, 0x8a, 0x00, 0x1c,
0xff, 0xff, 0xff, 0xe0,
0x00, 0x00, 0x36, 0xb0
};
LS Type: Summary-LSA (IP network)
LS Age: 3600 seconds
Do Not Age: False
Options: 0x02 (E)
Link-State Advertisement Type: Summary-LSA (IP network) (3)
Link State ID: 9.0.53.64
Advertising Router: 10.121.233.29 (10.121.233.29)
LS Sequence Number: 0x80000003
LS Checksum: 0x008a
Length: 28
Netmask: 255.255.255.224
Metric: 14000
You'll note that one byte of the checksum is 0x00; quagga would calculate the
checksum as 0xff8a.
It can be argued that the sourcing implementation generates an incorrect
checksum; however, rfc905 indicates that, for 1's complement arithmetic, the
value 255 shall be regarded as 0, thus either values are valid.
EXPLANATION
The quagga ospfd and ospf6d implementations operate by copying the PDU's
existing checksum in a holding variable, calculating the checksum, and comparing
the resulting checksum to the original. As a note, this implementation has the
side effect of modifying the contents of the PDU.
Evaluation of both rfc905 and rfc1008 shows that checksum validation should
involve calculating the sum over the PDU and checking that both resulting C0 and
C1 values are zero. This behavior is enacted in the rfc1008 implementation by
calling encodecc with k = 0 (checksum offset); however, this functionality had
been omitted from the quagga implementation.
PATCH
This patch adds the ability to call the quagga's fletcher_checksum() with a
checksum offset value of 0xffff (aka FLETCHER_CHECKSUM_VALIDATE) which returns
the sum over the buffer (a value of 0 indicates a valid checksum). This is
similar to the mechanism in rfc1008 when called with k = 0. The patch also
introduces ospf_lsa_checksum_valid().
ospf6d had it's own implementation of the fletcher checksum in
ospf6_lsa_checksum(); it's the same algorithm as in fletcher_checksum(). This
patch removes the local implementation in favor of the library's as well as creates
and uses ospf6_lsa_checksum_valid().
quagga's ISIS implementation suffers from the same problem; however, I do not
have the facilities to validate a fix to ISIS, thus this change has been left to
the ISIS maintainers. The function iso_csum_verify() should be reduced to
running the fletcher checksum over the buffer using an offset of 0.
Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-09-13 19:17:36 +02:00
|
|
|
int ospf_lsa_checksum_valid(struct lsa_header *lsa)
|
|
|
|
{
|
2020-04-08 07:57:15 +02:00
|
|
|
uint8_t *buffer = &lsa->options;
|
2018-03-27 21:13:34 +02:00
|
|
|
int options_offset = buffer - (uint8_t *)&lsa->ls_age; /* should be 2 */
|
lib: improve fletcher checksum validation
OVERVIEW
The checksum used in OSPF (rfc2328) is specified in rc905 annex B. There is an
sample implementation in rfc1008 which forms the basis of the quagga
implementation. This algorithm works perfectly when generating a checksum;
however, validation is a bit problematic.
The following LSA (generated by a non-quagga implementation) is received by
quagga and marked with an invalid checksum; however, it passes both the rfc905
and rfc1008 validation checks.
static uint8_t lsa_10_121_233_29[] = {
0x0e, 0x10, 0x02, 0x03,
0x09, 0x00, 0x35, 0x40,
0x0a, 0x79, 0xe9, 0x1d,
0x80, 0x00, 0x00, 0x03,
0x00, 0x8a, 0x00, 0x1c,
0xff, 0xff, 0xff, 0xe0,
0x00, 0x00, 0x36, 0xb0
};
LS Type: Summary-LSA (IP network)
LS Age: 3600 seconds
Do Not Age: False
Options: 0x02 (E)
Link-State Advertisement Type: Summary-LSA (IP network) (3)
Link State ID: 9.0.53.64
Advertising Router: 10.121.233.29 (10.121.233.29)
LS Sequence Number: 0x80000003
LS Checksum: 0x008a
Length: 28
Netmask: 255.255.255.224
Metric: 14000
You'll note that one byte of the checksum is 0x00; quagga would calculate the
checksum as 0xff8a.
It can be argued that the sourcing implementation generates an incorrect
checksum; however, rfc905 indicates that, for 1's complement arithmetic, the
value 255 shall be regarded as 0, thus either values are valid.
EXPLANATION
The quagga ospfd and ospf6d implementations operate by copying the PDU's
existing checksum in a holding variable, calculating the checksum, and comparing
the resulting checksum to the original. As a note, this implementation has the
side effect of modifying the contents of the PDU.
Evaluation of both rfc905 and rfc1008 shows that checksum validation should
involve calculating the sum over the PDU and checking that both resulting C0 and
C1 values are zero. This behavior is enacted in the rfc1008 implementation by
calling encodecc with k = 0 (checksum offset); however, this functionality had
been omitted from the quagga implementation.
PATCH
This patch adds the ability to call the quagga's fletcher_checksum() with a
checksum offset value of 0xffff (aka FLETCHER_CHECKSUM_VALIDATE) which returns
the sum over the buffer (a value of 0 indicates a valid checksum). This is
similar to the mechanism in rfc1008 when called with k = 0. The patch also
introduces ospf_lsa_checksum_valid().
ospf6d had it's own implementation of the fletcher checksum in
ospf6_lsa_checksum(); it's the same algorithm as in fletcher_checksum(). This
patch removes the local implementation in favor of the library's as well as creates
and uses ospf6_lsa_checksum_valid().
quagga's ISIS implementation suffers from the same problem; however, I do not
have the facilities to validate a fix to ISIS, thus this change has been left to
the ISIS maintainers. The function iso_csum_verify() should be reduced to
running the fletcher checksum over the buffer using an offset of 0.
Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-09-13 19:17:36 +02:00
|
|
|
|
|
|
|
/* Skip the AGE field */
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t len = ntohs(lsa->length) - options_offset;
|
lib: improve fletcher checksum validation
OVERVIEW
The checksum used in OSPF (rfc2328) is specified in rc905 annex B. There is an
sample implementation in rfc1008 which forms the basis of the quagga
implementation. This algorithm works perfectly when generating a checksum;
however, validation is a bit problematic.
The following LSA (generated by a non-quagga implementation) is received by
quagga and marked with an invalid checksum; however, it passes both the rfc905
and rfc1008 validation checks.
static uint8_t lsa_10_121_233_29[] = {
0x0e, 0x10, 0x02, 0x03,
0x09, 0x00, 0x35, 0x40,
0x0a, 0x79, 0xe9, 0x1d,
0x80, 0x00, 0x00, 0x03,
0x00, 0x8a, 0x00, 0x1c,
0xff, 0xff, 0xff, 0xe0,
0x00, 0x00, 0x36, 0xb0
};
LS Type: Summary-LSA (IP network)
LS Age: 3600 seconds
Do Not Age: False
Options: 0x02 (E)
Link-State Advertisement Type: Summary-LSA (IP network) (3)
Link State ID: 9.0.53.64
Advertising Router: 10.121.233.29 (10.121.233.29)
LS Sequence Number: 0x80000003
LS Checksum: 0x008a
Length: 28
Netmask: 255.255.255.224
Metric: 14000
You'll note that one byte of the checksum is 0x00; quagga would calculate the
checksum as 0xff8a.
It can be argued that the sourcing implementation generates an incorrect
checksum; however, rfc905 indicates that, for 1's complement arithmetic, the
value 255 shall be regarded as 0, thus either values are valid.
EXPLANATION
The quagga ospfd and ospf6d implementations operate by copying the PDU's
existing checksum in a holding variable, calculating the checksum, and comparing
the resulting checksum to the original. As a note, this implementation has the
side effect of modifying the contents of the PDU.
Evaluation of both rfc905 and rfc1008 shows that checksum validation should
involve calculating the sum over the PDU and checking that both resulting C0 and
C1 values are zero. This behavior is enacted in the rfc1008 implementation by
calling encodecc with k = 0 (checksum offset); however, this functionality had
been omitted from the quagga implementation.
PATCH
This patch adds the ability to call the quagga's fletcher_checksum() with a
checksum offset value of 0xffff (aka FLETCHER_CHECKSUM_VALIDATE) which returns
the sum over the buffer (a value of 0 indicates a valid checksum). This is
similar to the mechanism in rfc1008 when called with k = 0. The patch also
introduces ospf_lsa_checksum_valid().
ospf6d had it's own implementation of the fletcher checksum in
ospf6_lsa_checksum(); it's the same algorithm as in fletcher_checksum(). This
patch removes the local implementation in favor of the library's as well as creates
and uses ospf6_lsa_checksum_valid().
quagga's ISIS implementation suffers from the same problem; however, I do not
have the facilities to validate a fix to ISIS, thus this change has been left to
the ISIS maintainers. The function iso_csum_verify() should be reduced to
running the fletcher checksum over the buffer using an offset of 0.
Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Reviewed-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2012-09-13 19:17:36 +02:00
|
|
|
|
|
|
|
return (fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE)
|
|
|
|
== 0);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Create OSPF LSA. */
|
2019-01-24 10:12:36 +01:00
|
|
|
struct ospf_lsa *ospf_lsa_new(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
|
|
|
|
new = XCALLOC(MTYPE_OSPF_LSA, sizeof(struct ospf_lsa));
|
|
|
|
|
|
|
|
new->flags = 0;
|
|
|
|
new->lock = 1;
|
|
|
|
new->retransmit_counter = 0;
|
2017-01-17 22:46:07 +01:00
|
|
|
monotime(&new->tv_recv);
|
2002-12-13 21:15:29 +01:00
|
|
|
new->tv_orig = new->tv_recv;
|
|
|
|
new->refresh_list = -1;
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = VRF_DEFAULT;
|
2020-08-22 19:49:30 +02:00
|
|
|
new->to_be_acknowledged = 0;
|
2022-10-16 17:19:37 +02:00
|
|
|
new->opaque_zero_len_delete = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2018-08-21 02:41:37 +02:00
|
|
|
struct ospf_lsa *ospf_lsa_new_and_data(size_t size)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
|
|
|
|
new = ospf_lsa_new();
|
|
|
|
new->data = ospf_lsa_data_new(size);
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
new->size = size;
|
2018-08-21 02:41:37 +02:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Duplicate OSPF LSA. */
|
|
|
|
struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
|
|
|
|
if (lsa == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
new = XCALLOC(MTYPE_OSPF_LSA, sizeof(struct ospf_lsa));
|
|
|
|
|
|
|
|
memcpy(new, lsa, sizeof(struct ospf_lsa));
|
|
|
|
UNSET_FLAG(new->flags, OSPF_LSA_DISCARD);
|
|
|
|
new->lock = 1;
|
|
|
|
new->retransmit_counter = 0;
|
|
|
|
new->data = ospf_lsa_data_dup(lsa->data);
|
|
|
|
|
2002-12-13 22:44:27 +01:00
|
|
|
/* kevinm: Clear the refresh_list, otherwise there are going
|
|
|
|
to be problems when we try to remove the LSA from the
|
|
|
|
queue (which it's not a member of.)
|
|
|
|
XXX: Should we add the LSA to the refresh_list queue? */
|
|
|
|
new->refresh_list = -1;
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA))
|
2015-03-03 08:51:53 +01:00
|
|
|
zlog_debug("LSA: duplicated %p (new: %p)", (void *)lsa,
|
|
|
|
(void *)new);
|
2002-12-13 22:44:27 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free OSPF LSA. */
|
|
|
|
void ospf_lsa_free(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
assert(lsa->lock == 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA))
|
2015-03-03 08:51:53 +01:00
|
|
|
zlog_debug("LSA: freed %p", (void *)lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Delete LSA data. */
|
|
|
|
if (lsa->data != NULL)
|
|
|
|
ospf_lsa_data_free(lsa->data);
|
|
|
|
|
|
|
|
assert(lsa->refresh_list < 0);
|
|
|
|
|
|
|
|
memset(lsa, 0, sizeof(struct ospf_lsa));
|
|
|
|
XFREE(MTYPE_OSPF_LSA, lsa);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lock LSA. */
|
|
|
|
struct ospf_lsa *ospf_lsa_lock(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
lsa->lock++;
|
|
|
|
return lsa;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock LSA. */
|
2006-07-26 11:37:26 +02:00
|
|
|
void ospf_lsa_unlock(struct ospf_lsa **lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* This is sanity check. */
|
2006-07-26 11:37:26 +02:00
|
|
|
if (!lsa || !*lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
|
2006-07-26 11:37:26 +02:00
|
|
|
(*lsa)->lock--;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2010-04-13 23:33:54 +02:00
|
|
|
assert((*lsa)->lock >= 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-07-26 11:37:26 +02:00
|
|
|
if ((*lsa)->lock == 0) {
|
|
|
|
assert(CHECK_FLAG((*lsa)->flags, OSPF_LSA_DISCARD));
|
|
|
|
ospf_lsa_free(*lsa);
|
|
|
|
*lsa = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check discard flag. */
|
|
|
|
void ospf_lsa_discard(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
if (!CHECK_FLAG(lsa->flags, OSPF_LSA_DISCARD)) {
|
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_DISCARD);
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create LSA data. */
|
|
|
|
struct lsa_header *ospf_lsa_data_new(size_t size)
|
|
|
|
{
|
2008-08-18 23:13:29 +02:00
|
|
|
return XCALLOC(MTYPE_OSPF_LSA_DATA, size);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Duplicate LSA data. */
|
|
|
|
struct lsa_header *ospf_lsa_data_dup(struct lsa_header *lsah)
|
|
|
|
{
|
|
|
|
struct lsa_header *new;
|
|
|
|
|
|
|
|
new = ospf_lsa_data_new(ntohs(lsah->length));
|
|
|
|
memcpy(new, lsah, ntohs(lsah->length));
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free LSA data. */
|
|
|
|
void ospf_lsa_data_free(struct lsa_header *lsah)
|
|
|
|
{
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA))
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: data freed %p", lsah->type,
|
|
|
|
&lsah->id, (void *)lsah);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
XFREE(MTYPE_OSPF_LSA_DATA, lsah);
|
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSA general functions. */
|
|
|
|
|
|
|
|
const char *dump_lsa_key(struct ospf_lsa *lsa)
|
|
|
|
{
|
2019-11-20 17:26:59 +01:00
|
|
|
static char buf[sizeof("Type255,id(255.255.255.255),ar(255.255.255.255)")+1];
|
2002-12-13 21:15:29 +01:00
|
|
|
struct lsa_header *lsah;
|
|
|
|
|
|
|
|
if (lsa != NULL && (lsah = lsa->data) != NULL) {
|
|
|
|
char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
|
2020-10-21 19:56:26 +02:00
|
|
|
inet_ntop(AF_INET, &lsah->id, id, sizeof(id));
|
|
|
|
inet_ntop(AF_INET, &lsah->adv_router, ar, sizeof(ar));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-04-20 20:12:38 +02:00
|
|
|
snprintf(buf, sizeof(buf), "Type%d,id(%s),ar(%s)", lsah->type,
|
|
|
|
id, ar);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else
|
2017-10-22 20:36:13 +02:00
|
|
|
strlcpy(buf, "NULL", sizeof(buf));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t lsa_seqnum_increment(struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t seqnum;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
seqnum = ntohl(lsa->data->ls_seqnum) + 1;
|
|
|
|
|
|
|
|
return htonl(seqnum);
|
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
void lsa_header_set(struct stream *s, uint8_t options, uint8_t type,
|
2003-03-25 06:07:42 +01:00
|
|
|
struct in_addr id, struct in_addr router_id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
|
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
|
|
|
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
lsah->ls_age = htons(OSPF_LSA_INITIAL_AGE);
|
2002-12-13 21:15:29 +01:00
|
|
|
lsah->options = options;
|
|
|
|
lsah->type = type;
|
|
|
|
lsah->id = id;
|
2003-03-25 06:07:42 +01:00
|
|
|
lsah->adv_router = router_id;
|
2002-12-13 21:15:29 +01:00
|
|
|
lsah->ls_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
|
|
|
|
|
2005-02-09 16:51:56 +01:00
|
|
|
stream_forward_endp(s, OSPF_LSA_HEADER_SIZE);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* router-LSA related functions. */
|
|
|
|
/* Get router-LSA flags. */
|
2020-08-05 10:44:21 +02:00
|
|
|
uint8_t router_lsa_flags(struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t flags;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
flags = area->ospf->flags;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set virtual link flag. */
|
|
|
|
if (ospf_full_virtual_nbrs(area))
|
|
|
|
SET_FLAG(flags, ROUTER_LSA_VIRTUAL);
|
|
|
|
else
|
|
|
|
/* Just sanity check */
|
|
|
|
UNSET_FLAG(flags, ROUTER_LSA_VIRTUAL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set Shortcut ABR behabiour flag. */
|
|
|
|
UNSET_FLAG(flags, ROUTER_LSA_SHORTCUT);
|
2003-03-25 06:07:42 +01:00
|
|
|
if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!OSPF_IS_AREA_BACKBONE(area))
|
|
|
|
if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT
|
2003-03-25 06:07:42 +01:00
|
|
|
&& area->ospf->backbone == NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
|| area->shortcut_configured
|
|
|
|
== OSPF_SHORTCUT_ENABLE)
|
|
|
|
SET_FLAG(flags, ROUTER_LSA_SHORTCUT);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* ASBR can't exit in stub area. */
|
2007-08-06 17:50:20 +02:00
|
|
|
if (area->external_routing == OSPF_AREA_STUB)
|
2003-06-22 10:22:18 +02:00
|
|
|
UNSET_FLAG(flags, ROUTER_LSA_EXTERNAL);
|
|
|
|
/* If ASBR set External flag */
|
|
|
|
else if (IS_OSPF_ASBR(area->ospf))
|
|
|
|
SET_FLAG(flags, ROUTER_LSA_EXTERNAL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-06-22 10:22:18 +02:00
|
|
|
/* Set ABR dependent flags */
|
|
|
|
if (IS_OSPF_ABR(area->ospf)) {
|
|
|
|
SET_FLAG(flags, ROUTER_LSA_BORDER);
|
|
|
|
/* If Area is NSSA and we are both ABR and unconditional
|
|
|
|
* translator,
|
2003-07-12 23:30:57 +02:00
|
|
|
* set Nt bit to inform other routers.
|
2003-06-22 10:22:18 +02:00
|
|
|
*/
|
2003-07-12 23:30:57 +02:00
|
|
|
if ((area->external_routing == OSPF_AREA_NSSA)
|
|
|
|
&& (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
|
|
|
|
SET_FLAG(flags, ROUTER_LSA_NT);
|
2003-06-22 10:22:18 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Lookup neighbor other than myself.
|
|
|
|
And check neighbor count,
|
|
|
|
Point-to-Point link must have only 1 neighbor. */
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_neighbor *nbr = NULL;
|
2003-03-25 06:07:42 +01:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Search neighbor, there must be one of two nbrs. */
|
2003-03-25 06:07:42 +01:00
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
|
|
|
|
if ((nbr = rn->info))
|
|
|
|
if (!IPV4_ADDR_SAME(&nbr->router_id,
|
|
|
|
&oi->ospf->router_id))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (nbr->state == NSM_Full) {
|
2003-03-25 06:07:42 +01:00
|
|
|
route_unlock_node(rn);
|
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* PtoP link must have only 1 neighbor. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (ospf_nbr_count(oi, 0) > 1)
|
2022-12-12 16:12:34 +01:00
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_PTP_NEIGHBOR,
|
|
|
|
"Point-to-Point link on interface %s has more than 1 neighbor.",
|
|
|
|
oi->ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return nbr;
|
|
|
|
}
|
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* Determine cost of link, taking RFC3137 stub-router support into
|
|
|
|
* consideration
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint16_t ospf_link_cost(struct ospf_interface *oi)
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
{
|
|
|
|
/* RFC3137 stub router support */
|
|
|
|
if (!CHECK_FLAG(oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
|
|
|
|
return oi->output_cost;
|
|
|
|
else
|
|
|
|
return OSPF_OUTPUT_COST_INFINITE;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set a link information. */
|
2020-08-05 10:44:21 +02:00
|
|
|
char link_info_set(struct stream **s, struct in_addr id, struct in_addr data,
|
|
|
|
uint8_t type, uint8_t tos, uint16_t cost)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2006-01-18 16:07:38 +01:00
|
|
|
/* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
|
|
|
|
* vast majority of cases. Some rare routers with lots of links need
|
|
|
|
* more.
|
2022-04-19 14:29:58 +02:00
|
|
|
* we try accommodate those here.
|
2006-01-18 16:07:38 +01:00
|
|
|
*/
|
2018-08-22 02:22:28 +02:00
|
|
|
if (STREAM_WRITEABLE(*s) < OSPF_ROUTER_LSA_LINK_SIZE) {
|
2006-01-18 16:07:38 +01:00
|
|
|
size_t ret = OSPF_MAX_LSA_SIZE;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-01-18 16:07:38 +01:00
|
|
|
/* Can we enlarge the stream still? */
|
2018-08-22 02:22:28 +02:00
|
|
|
if (STREAM_SIZE(*s) == OSPF_MAX_LSA_SIZE) {
|
2006-01-18 16:07:38 +01:00
|
|
|
/* we futz the size here for simplicity, really we need
|
|
|
|
* to account
|
|
|
|
* for just:
|
2020-03-08 20:43:26 +01:00
|
|
|
* IP Header - (sizeof(struct ip))
|
2006-01-18 16:07:38 +01:00
|
|
|
* OSPF Header - OSPF_HEADER_SIZE
|
|
|
|
* LSA Header - OSPF_LSA_HEADER_SIZE
|
|
|
|
* MD5 auth data, if MD5 is configured -
|
|
|
|
* OSPF_AUTH_MD5_SIZE.
|
|
|
|
*
|
|
|
|
* Simpler just to subtract OSPF_MAX_LSA_SIZE though.
|
|
|
|
*/
|
2018-08-22 02:22:28 +02:00
|
|
|
ret = stream_resize_inplace(
|
2017-07-22 14:52:33 +02:00
|
|
|
s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
|
2006-01-18 16:07:38 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-01-18 16:07:38 +01:00
|
|
|
if (ret == OSPF_MAX_LSA_SIZE) {
|
2018-08-21 15:22:33 +02:00
|
|
|
flog_warn(
|
2018-09-13 20:56:04 +02:00
|
|
|
EC_OSPF_LSA_SIZE,
|
2009-08-03 17:34:16 +02:00
|
|
|
"%s: Out of space in LSA stream, left %zd, size %zd",
|
2018-08-22 02:22:28 +02:00
|
|
|
__func__, STREAM_WRITEABLE(*s),
|
|
|
|
STREAM_SIZE(*s));
|
2006-01-18 16:07:38 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* TOS based routing is not supported. */
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_put_ipv4(*s, id.s_addr); /* Link ID. */
|
|
|
|
stream_put_ipv4(*s, data.s_addr); /* Link Data. */
|
|
|
|
stream_putc(*s, type); /* Link Type. */
|
|
|
|
stream_putc(*s, tos); /* TOS = 0. */
|
|
|
|
stream_putw(*s, cost); /* Link Cost. */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-01-18 16:07:38 +01:00
|
|
|
return 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
/* Describe Point-to-Point link (Section 12.4.1.1). */
|
2021-02-17 01:51:52 +01:00
|
|
|
|
|
|
|
/* Note: If the interface is configured as point-to-point dmvpn then the other
|
|
|
|
* end of link is dmvpn hub with point-to-multipoint ospf network type. The
|
|
|
|
* hub then expects this router to populate the stub network and also Link Data
|
|
|
|
* Field set to IP Address and not MIB-II ifIndex
|
|
|
|
*/
|
2018-08-22 02:22:28 +02:00
|
|
|
static int lsa_link_ptop_set(struct stream **s, struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int links = 0;
|
|
|
|
struct ospf_neighbor *nbr;
|
2015-05-20 02:58:13 +02:00
|
|
|
struct in_addr id, mask, data;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t cost = ospf_link_cost(oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type1]: Set link Point-to-Point");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
if ((nbr = ospf_nbr_lookup_ptop(oi)))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (nbr->state == NSM_Full) {
|
2015-05-20 02:58:13 +02:00
|
|
|
if (CHECK_FLAG(oi->connected->flags,
|
2021-02-17 01:51:52 +01:00
|
|
|
ZEBRA_IFA_UNNUMBERED)
|
|
|
|
&& !oi->ptp_dmvpn) {
|
2015-05-20 02:58:13 +02:00
|
|
|
/* For unnumbered point-to-point networks, the
|
|
|
|
Link Data field
|
|
|
|
should specify the interface's MIB-II ifIndex
|
|
|
|
value. */
|
|
|
|
data.s_addr = htonl(oi->ifp->ifindex);
|
|
|
|
links += link_info_set(
|
|
|
|
s, nbr->router_id, data,
|
|
|
|
LSA_LINK_TYPE_POINTOPOINT, 0, cost);
|
|
|
|
} else {
|
|
|
|
links += link_info_set(
|
|
|
|
s, nbr->router_id,
|
|
|
|
oi->address->u.prefix4,
|
|
|
|
LSA_LINK_TYPE_POINTOPOINT, 0, cost);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:58:13 +02:00
|
|
|
/* no need for a stub link for unnumbered interfaces */
|
2021-02-17 01:51:52 +01:00
|
|
|
if (oi->ptp_dmvpn
|
|
|
|
|| !CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED)) {
|
2015-05-20 02:58:13 +02:00
|
|
|
/* Regardless of the state of the neighboring router, we must
|
|
|
|
add a Type 3 link (stub network).
|
|
|
|
N.B. Options 1 & 2 share basically the same logic. */
|
|
|
|
masklen2ip(oi->address->prefixlen, &mask);
|
|
|
|
id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr
|
|
|
|
& mask.s_addr;
|
|
|
|
links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0,
|
|
|
|
oi->output_cost);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return links;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Describe Broadcast Link. */
|
2018-08-22 02:22:28 +02:00
|
|
|
static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_neighbor *dr;
|
|
|
|
struct in_addr id, mask;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t cost = ospf_link_cost(oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Describe Type 3 Link. */
|
|
|
|
if (oi->state == ISM_Waiting) {
|
2014-04-28 13:42:20 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"LSA[Type1]: Interface %s is in state Waiting. Adding stub interface",
|
2014-04-28 13:42:20 +02:00
|
|
|
oi->ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
masklen2ip(oi->address->prefixlen, &mask);
|
|
|
|
id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
|
2006-01-18 16:07:38 +01:00
|
|
|
return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0,
|
|
|
|
oi->output_cost);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
dr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi));
|
|
|
|
/* Describe Type 2 link. */
|
2017-07-22 14:52:33 +02:00
|
|
|
if (dr && (dr->state == NSM_Full
|
|
|
|
|| IPV4_ADDR_SAME(&oi->address->u.prefix4, &DR(oi)))
|
2003-03-25 06:07:42 +01:00
|
|
|
&& ospf_nbr_count(oi, NSM_Full) > 0) {
|
2014-04-28 13:42:20 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"LSA[Type1]: Interface %s has a DR. Adding transit interface",
|
2014-04-28 13:42:20 +02:00
|
|
|
oi->ifp->name);
|
2006-01-18 16:07:38 +01:00
|
|
|
return link_info_set(s, DR(oi), oi->address->u.prefix4,
|
|
|
|
LSA_LINK_TYPE_TRANSIT, 0, cost);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
/* Describe type 3 link. */
|
|
|
|
else {
|
2014-04-28 13:42:20 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
2020-03-27 12:35:23 +01:00
|
|
|
"LSA[Type1]: Interface %s has no DR. Adding stub interface",
|
2014-04-28 13:42:20 +02:00
|
|
|
oi->ifp->name);
|
2002-12-13 21:15:29 +01:00
|
|
|
masklen2ip(oi->address->prefixlen, &mask);
|
|
|
|
id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
|
2006-01-18 16:07:38 +01:00
|
|
|
return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0,
|
|
|
|
oi->output_cost);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2018-08-22 02:22:28 +02:00
|
|
|
static int lsa_link_loopback_set(struct stream **s, struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr id, mask;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Describe Type 3 Link. */
|
|
|
|
if (oi->state != ISM_Loopback)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
mask.s_addr = 0xffffffff;
|
|
|
|
id.s_addr = oi->address->u.prefix4.s_addr;
|
2016-02-19 06:33:40 +01:00
|
|
|
return link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Describe Virtual Link. */
|
2018-08-22 02:22:28 +02:00
|
|
|
static int lsa_link_virtuallink_set(struct stream **s,
|
|
|
|
struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_neighbor *nbr;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t cost = ospf_link_cost(oi);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (oi->state == ISM_PointToPoint)
|
2003-03-25 06:07:42 +01:00
|
|
|
if ((nbr = ospf_nbr_lookup_ptop(oi)))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (nbr->state == NSM_Full) {
|
2006-01-18 16:07:38 +01:00
|
|
|
return link_info_set(s, nbr->router_id,
|
|
|
|
oi->address->u.prefix4,
|
|
|
|
LSA_LINK_TYPE_VIRTUALLINK,
|
|
|
|
0, cost);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
|
|
|
|
|
2002-12-13 21:59:45 +01:00
|
|
|
/* this function add for support point-to-multipoint ,see rfc2328
|
|
|
|
12.4.1.4.*/
|
|
|
|
/* from "edward rrr" <edward_rrr@hotmail.com>
|
|
|
|
http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
|
2018-08-22 02:22:28 +02:00
|
|
|
static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi)
|
2002-12-13 21:59:45 +01:00
|
|
|
{
|
|
|
|
int links = 0;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_neighbor *nbr = NULL;
|
|
|
|
struct in_addr id, mask;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t cost = ospf_link_cost(oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:59:45 +01:00
|
|
|
mask.s_addr = 0xffffffff;
|
|
|
|
id.s_addr = oi->address->u.prefix4.s_addr;
|
2006-01-18 16:07:38 +01:00
|
|
|
links += link_info_set(s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-05 21:34:32 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("PointToMultipoint: running ptomultip_set");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:59:45 +01:00
|
|
|
/* Search neighbor, */
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
|
|
|
|
if ((nbr = rn->info) != NULL)
|
|
|
|
/* Ignore myself. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (!IPV4_ADDR_SAME(&nbr->router_id,
|
|
|
|
&oi->ospf->router_id))
|
2002-12-13 21:59:45 +01:00
|
|
|
if (nbr->state == NSM_Full)
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:59:45 +01:00
|
|
|
{
|
2006-01-18 16:07:38 +01:00
|
|
|
links += link_info_set(
|
|
|
|
s, nbr->router_id,
|
|
|
|
oi->address->u.prefix4,
|
|
|
|
LSA_LINK_TYPE_POINTOPOINT, 0,
|
|
|
|
cost);
|
2003-04-05 21:34:32 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"PointToMultipoint: set link to %pI4",
|
|
|
|
&oi->address->u.prefix4);
|
2002-12-13 21:59:45 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:59:45 +01:00
|
|
|
return links;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set router-LSA link information. */
|
2018-08-22 02:22:28 +02:00
|
|
|
static int router_lsa_link_set(struct stream **s, struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct ospf_interface *oi;
|
2002-12-13 21:15:29 +01:00
|
|
|
int links = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
struct interface *ifp = oi->ifp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check interface is up, OSPF is enable. */
|
2002-12-13 22:03:13 +01:00
|
|
|
if (if_is_operative(ifp)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (oi->state != ISM_Down) {
|
2012-07-07 17:06:11 +02:00
|
|
|
oi->lsa_pos_beg = links;
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Describe each link. */
|
|
|
|
switch (oi->type) {
|
|
|
|
case OSPF_IFTYPE_POINTOPOINT:
|
|
|
|
links += lsa_link_ptop_set(s, oi);
|
|
|
|
break;
|
|
|
|
case OSPF_IFTYPE_BROADCAST:
|
|
|
|
links += lsa_link_broadcast_set(s, oi);
|
|
|
|
break;
|
|
|
|
case OSPF_IFTYPE_NBMA:
|
|
|
|
links += lsa_link_nbma_set(s, oi);
|
|
|
|
break;
|
|
|
|
case OSPF_IFTYPE_POINTOMULTIPOINT:
|
2003-03-25 06:07:42 +01:00
|
|
|
links += lsa_link_ptomp_set(s, oi);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_IFTYPE_VIRTUALLINK:
|
|
|
|
links +=
|
|
|
|
lsa_link_virtuallink_set(s, oi);
|
|
|
|
break;
|
|
|
|
case OSPF_IFTYPE_LOOPBACK:
|
|
|
|
links += lsa_link_loopback_set(s, oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-07-07 17:06:11 +02:00
|
|
|
oi->lsa_pos_end = links;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return links;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set router-LSA body. */
|
2020-08-05 10:44:21 +02:00
|
|
|
void ospf_router_lsa_body_set(struct stream **s, struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
unsigned long putp;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t cnt;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set flags. */
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_putc(*s, router_lsa_flags(area));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set Zero fields. */
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_putc(*s, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Keep pointer to # links. */
|
2018-08-22 02:22:28 +02:00
|
|
|
putp = stream_get_endp(*s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Forward word */
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_putw(*s, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set all link information. */
|
|
|
|
cnt = router_lsa_link_set(s, area);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set # of links here. */
|
2018-08-22 02:22:28 +02:00
|
|
|
stream_putw_at(*s, putp, cnt);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-02-23 01:04:25 +01:00
|
|
|
static void ospf_stub_router_timer(struct thread *t)
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
{
|
|
|
|
struct ospf_area *area = THREAD_ARG(t);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
area->t_stub_router = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
SET_FLAG(area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* clear stub route state and generate router-lsa refresh, don't
|
|
|
|
* clobber an administratively set stub-router state though.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
UNSET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_router_lsa_update_area(area);
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
static void ospf_stub_router_check(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
/* area must either be administratively configured to be stub
|
|
|
|
* or startup-time stub-router must be configured and we must in a
|
|
|
|
* pre-stub
|
|
|
|
* state.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) {
|
|
|
|
SET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
|
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* not admin-stubbed, check whether startup stubbing is configured and
|
|
|
|
* whether it's not been done yet
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(area->stub_router_state,
|
|
|
|
OSPF_AREA_WAS_START_STUB_ROUTED))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
if (area->ospf->stub_router_startup_time
|
|
|
|
== OSPF_STUB_ROUTER_UNCONFIGURED) {
|
|
|
|
/* stub-router is hence done forever for this area, even if
|
|
|
|
* someone
|
|
|
|
* tries configure it (take effect next restart).
|
|
|
|
*/
|
|
|
|
SET_FLAG(area->stub_router_state,
|
|
|
|
OSPF_AREA_WAS_START_STUB_ROUTED);
|
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* startup stub-router configured and not yet done */
|
|
|
|
SET_FLAG(area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
OSPF_AREA_TIMER_ON(area->t_stub_router, ospf_stub_router_timer,
|
|
|
|
area->ospf->stub_router_startup_time);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new router-LSA. */
|
|
|
|
static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
|
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf *ospf = area->ospf;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct stream *s;
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
int length;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type1]: Create router-LSA instance");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support
* ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define.
(struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for
options, to allow shutdown to distinguish between complete
shutdown and shutdown of a subset of ospf instances.
(struct ospf)
Add stub_router_{startup,shutdown_}time, configuration of startup
and shutdown time for stub-router.
Add t_graceful_shutdown struct thread, timer for graceful
shutdown, if needed.
(struct ospf_area) Add stub_router_state - run time state of
stub-router for an area. Add flags for ADMIN, IS and WAS
states.
Add t_stub_router, timer thread to resend router-lsa for an
area.
* ospf_lsa.c: (ospf_link_cost) new simple function to spit out
either the given lnks cost or infinite cost if stub-router is
in effect.
(lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use
previous function for transit-links.
(ospf_stub_router_timer) timer thread for end of startup stub
router. Change state as required for the area and setup
re-origination of router-lsa.
(ospf_stub_router_check) Check/do whether stub-router should be
enabled, and whether it requires timer to be setup.
(ospf_router_lsa_new) call previous function at top.
(ospf_router_lsa_originate) no external callers, made static.
* ospf_lsa.h: (ospf_router_lsa_originate) removed.
* ospf_main.c: (sigint) make static.
remove call to exit, as ospf_terminate now deals with
exiting.
* ospf_route.c: (ospf_terminate) removed, now in ospfd.c.
* ospf_vty.c: (show_ip_ospf_area) print out state of
stub-router, if active.
(show_ip_ospf) print out configuration of stub-router
support, and details of graceful-shutdown if the timer is
active.
((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new
commands to (de-)?configure stub-router support.
(config_write_stub_router) write out config of stub-router.
(ospf_config_write) call previous.
(ospf_vty_init) install the new stub-router commands.
* ospfd.c: various functions made static.
(ospf_new) Set defaults for stub-router. Graceful shutdown
is made to default on, just to be adventerous.
(ospf_graceful_shutdown_finish) new function, final part of
shutdown.
(ospf_graceful_shutdown_timer) timer thread wrapper for
graceful-shutdown.
(ospf_graceful_shutdown_check) check whether to setup timer
for shutdown or proceed directly to final shutdown.
(ospf_terminate) moved here from ospf_route.c, call
ospf_finish for each instance.
(ospf_finish) renamed to ospf_finish_final and made static.
(ospf_finish) new function, exported wrapper around
ospf_graceful_shutdown_check.
(ospf_finish_final) complete shutdown of an instance.
Add missing TIMER_OFF's of two timer threads.
(ospf_area_free) opaque self lsa timer should be turned off.
2005-10-29 14:50:09 +02:00
|
|
|
/* check whether stub-router is desired, and if this is the first
|
|
|
|
* router LSA.
|
|
|
|
*/
|
|
|
|
ospf_stub_router_check(area);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create a stream for LSA. */
|
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
/* Set LSA common header fields. */
|
2003-07-12 23:30:57 +02:00
|
|
|
lsa_header_set(s, LSA_OPTIONS_GET(area) | LSA_OPTIONS_NSSA_GET(area),
|
|
|
|
OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set router-LSA body fields. */
|
2018-08-22 02:22:28 +02:00
|
|
|
ospf_router_lsa_body_set(&s, area);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
2006-01-18 16:07:38 +01:00
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
2002-12-13 21:15:29 +01:00
|
|
|
lsah->length = htons(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Now, create OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new->area = area;
|
2008-11-04 14:37:29 +01:00
|
|
|
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = area->ospf->vrf_id;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Copy LSA data to store, discard stream. */
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate Router-LSA. */
|
|
|
|
static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
|
2021-05-31 15:27:51 +02:00
|
|
|
if (area->ospf->gr_info.restart_in_progress) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
|
|
|
OSPF_ROUTER_LSA);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new router-LSA instance. */
|
2005-11-20 15:54:12 +01:00
|
|
|
if ((new = ospf_router_lsa_new(area)) == NULL) {
|
|
|
|
zlog_err("%s: ospf_router_lsa_new returned NULL", __func__);
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Sanity check. */
|
2020-02-06 07:49:02 +01:00
|
|
|
if (new->data->adv_router.s_addr == INADDR_ANY) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type1]: AdvRouter is 0, discard");
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_discard(new);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install LSA to LSDB. */
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_lsa_install(area->ospf, NULL, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Update LSA origination count. */
|
2003-03-25 06:07:42 +01:00
|
|
|
area->ospf->lsa_originate_count++;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Flooding new LSA through area. */
|
|
|
|
ospf_flood_through_area(area, NULL, new);
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Originate router-LSA %p",
|
|
|
|
new->data->type, &new->data->id,
|
2015-03-03 08:51:53 +01:00
|
|
|
(void *)new);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh router-LSA. */
|
|
|
|
static struct ospf_lsa *ospf_router_lsa_refresh(struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
struct ospf_area *area = lsa->area;
|
|
|
|
struct ospf_lsa *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Sanity check. */
|
|
|
|
assert(lsa->data);
|
|
|
|
|
|
|
|
/* Delete LSA from neighbor retransmit-list. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ls_retransmit_delete_nbr_area(area, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
/* Unregister LSA from refresh-list */
|
|
|
|
ospf_refresher_unregister_lsa(area->ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* Create new router-LSA instance. */
|
|
|
|
if ((new = ospf_router_lsa_new(area)) == NULL) {
|
|
|
|
zlog_err("%s: ospf_router_lsa_new returned NULL", __func__);
|
2005-11-20 15:54:12 +01:00
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ospf_lsa_install(area->ospf, NULL, new);
|
|
|
|
|
|
|
|
/* Flood LSA through area. */
|
|
|
|
ospf_flood_through_area(area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Debug logging. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: router-LSA refresh",
|
|
|
|
new->data->type, &new->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
int ospf_router_lsa_update_area(struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2010-01-24 23:42:13 +01:00
|
|
|
zlog_debug("[router-LSA]: (router-LSA area update)");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Now refresh router-LSA. */
|
|
|
|
if (area->router_lsa_self)
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_lsa_refresh(area->ospf, area->router_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Newly originate router-LSA. */
|
|
|
|
else
|
|
|
|
ospf_router_lsa_originate(area);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
int ospf_router_lsa_update(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_area *area;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("Timer[router-LSA Update]: (timer expire)");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *lsa = area->router_lsa_self;
|
|
|
|
struct router_lsa *rl;
|
2004-10-08 10:17:22 +02:00
|
|
|
const char *area_str;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Keep Area ID string. */
|
|
|
|
area_str = AREA_NAME(area);
|
|
|
|
|
|
|
|
/* If LSA not exist in this Area, originate new. */
|
|
|
|
if (lsa == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type1]: Create router-LSA for Area %s",
|
|
|
|
area_str);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ospf_router_lsa_originate(area);
|
|
|
|
}
|
|
|
|
/* If router-ID is changed, Link ID must change.
|
|
|
|
First flush old LSA, then originate new. */
|
2003-03-25 06:07:42 +01:00
|
|
|
else if (!IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Refresh router-LSA for Area %s",
|
2002-12-13 21:15:29 +01:00
|
|
|
lsa->data->type,
|
2020-10-21 19:56:26 +02:00
|
|
|
&lsa->data->id, area_str);
|
2010-04-14 11:32:12 +02:00
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_flush_area(lsa, area);
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&area->router_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
area->router_lsa_self = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Refresh router-LSA, (not install) and flood through
|
|
|
|
* area. */
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_router_lsa_update_area(area);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else {
|
|
|
|
rl = (struct router_lsa *)lsa->data;
|
|
|
|
/* Refresh router-LSA, (not install) and flood through
|
|
|
|
* area. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (rl->flags != ospf->flags)
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_router_lsa_update_area(area);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* network-LSA related functions. */
|
|
|
|
/* Originate Network-LSA. */
|
|
|
|
static void ospf_network_lsa_body_set(struct stream *s,
|
|
|
|
struct ospf_interface *oi)
|
|
|
|
{
|
|
|
|
struct in_addr mask;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_neighbor *nbr;
|
|
|
|
|
|
|
|
masklen2ip(oi->address->prefixlen, &mask);
|
|
|
|
stream_put_ipv4(s, mask.s_addr);
|
|
|
|
|
|
|
|
/* The network-LSA lists those routers that are fully adjacent to
|
|
|
|
the Designated Router; each fully adjacent router is identified by
|
|
|
|
its OSPF Router ID. The Designated Router includes itself in this
|
|
|
|
list. RFC2328, Section 12.4.2 */
|
|
|
|
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
|
|
|
|
if ((nbr = rn->info) != NULL)
|
|
|
|
if (nbr->state == NSM_Full || nbr == oi->nbr_self)
|
|
|
|
stream_put_ipv4(s, nbr->router_id.s_addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct lsa_header *lsah;
|
2009-10-13 17:13:13 +02:00
|
|
|
struct ospf_if_params *oip;
|
2002-12-13 21:15:29 +01:00
|
|
|
int length;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If there are no neighbours on this network (the net is stub),
|
|
|
|
the router does not originate network-LSA (see RFC 12.4.2) */
|
|
|
|
if (oi->full_nbrs == 0)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type2]: Create network-LSA instance");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new stream for LSA. */
|
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
lsa_header_set(s, (OPTIONS(oi) | LSA_OPTIONS_GET(oi->area)),
|
2003-03-25 06:07:42 +01:00
|
|
|
OSPF_NETWORK_LSA, DR(oi), oi->ospf->router_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set network-LSA body fields. */
|
|
|
|
ospf_network_lsa_body_set(s, oi);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
|
|
|
lsah->length = htons(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new->area = oi->area;
|
2008-11-04 14:37:29 +01:00
|
|
|
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = oi->ospf->vrf_id;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Copy LSA to store. */
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-10-13 17:13:13 +02:00
|
|
|
/* Remember prior network LSA sequence numbers, even if we stop
|
|
|
|
* originating one for this oi, to try avoid re-originating LSAs with a
|
|
|
|
* prior sequence number, and thus speed up adjency forming &
|
|
|
|
* convergence.
|
|
|
|
*/
|
|
|
|
if ((oip = ospf_lookup_if_params(oi->ifp, oi->address->u.prefix4))) {
|
|
|
|
new->data->ls_seqnum = oip->network_lsa_seqnum;
|
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(new);
|
|
|
|
} else {
|
|
|
|
oip = ospf_get_if_params(oi->ifp, oi->address->u.prefix4);
|
|
|
|
ospf_if_update_params(oi->ifp, oi->address->u.prefix4);
|
|
|
|
}
|
|
|
|
oip->network_lsa_seqnum = new->data->ls_seqnum;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate network-LSA. */
|
2010-01-24 23:42:13 +01:00
|
|
|
void ospf_network_lsa_update(struct ospf_interface *oi)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
|
2021-05-31 15:27:51 +02:00
|
|
|
if (oi->area->ospf->gr_info.restart_in_progress) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
|
|
|
OSPF_NETWORK_LSA);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
if (oi->network_lsa_self != NULL) {
|
|
|
|
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* Create new network-LSA instance. */
|
|
|
|
new = ospf_network_lsa_new(oi);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (new == NULL)
|
2017-07-17 14:03:14 +02:00
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Install LSA to LSDB. */
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_lsa_install(oi->ospf, oi, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Update LSA origination count. */
|
|
|
|
oi->ospf->lsa_originate_count++;
|
|
|
|
|
|
|
|
/* Flooding new LSA through area. */
|
|
|
|
ospf_flood_through_area(oi->area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Originate network-LSA %p",
|
|
|
|
new->data->type, &new->data->id,
|
2015-03-03 08:51:53 +01:00
|
|
|
(void *)new);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_area *area = lsa->area;
|
2010-01-24 23:42:13 +01:00
|
|
|
struct ospf_lsa *new, *new2;
|
2009-10-13 17:13:13 +02:00
|
|
|
struct ospf_if_params *oip;
|
2010-04-15 09:11:51 +02:00
|
|
|
struct ospf_interface *oi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(lsa->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-15 09:11:51 +02:00
|
|
|
/* Retrieve the oi for the network LSA */
|
|
|
|
oi = ospf_if_lookup_by_local_addr(area->ospf, NULL, lsa->data->id);
|
|
|
|
if (oi == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: network-LSA refresh: no oi found, ick, ignoring.",
|
|
|
|
lsa->data->type, &lsa->data->id);
|
2010-04-15 09:11:51 +02:00
|
|
|
ospf_lsa_header_dump(lsa->data);
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-11-21 13:50:16 +01:00
|
|
|
|
|
|
|
if (oi->state != ISM_DR)
|
|
|
|
return NULL;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Delete LSA from neighbor retransmit-list. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ls_retransmit_delete_nbr_area(area, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
/* Unregister LSA from refresh-list */
|
|
|
|
ospf_refresher_unregister_lsa(area->ospf, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new network-LSA instance. */
|
|
|
|
new = ospf_network_lsa_new(oi);
|
|
|
|
if (new == NULL)
|
2010-01-24 23:42:13 +01:00
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-10-13 17:13:13 +02:00
|
|
|
oip = ospf_lookup_if_params(oi->ifp, oi->address->u.prefix4);
|
|
|
|
assert(oip != NULL);
|
|
|
|
oip->network_lsa_seqnum = new->data->ls_seqnum =
|
|
|
|
lsa_seqnum_increment(lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
new2 = ospf_lsa_install(area->ospf, oi, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
assert(new2 == new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flood LSA through aera. */
|
|
|
|
ospf_flood_through_area(area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: network-LSA refresh",
|
|
|
|
new->data->type, &new->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
return new;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
static void stream_put_ospf_metric(struct stream *s, uint32_t metric_value)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t metric;
|
2002-12-13 21:15:29 +01:00
|
|
|
char *mp;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Put 0 metric. TOS metric is not supported. */
|
|
|
|
metric = htonl(metric_value);
|
|
|
|
mp = (char *)&metric;
|
|
|
|
mp++;
|
|
|
|
stream_put(s, mp, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* summary-LSA related functions. */
|
|
|
|
static void ospf_summary_lsa_body_set(struct stream *s, struct prefix *p,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr mask;
|
|
|
|
|
|
|
|
masklen2ip(p->prefixlen, &mask);
|
|
|
|
|
|
|
|
/* Put Network Mask. */
|
|
|
|
stream_put_ipv4(s, mask.s_addr);
|
|
|
|
|
|
|
|
/* Set # TOS. */
|
2018-03-27 21:13:34 +02:00
|
|
|
stream_putc(s, (uint8_t)0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set metric. */
|
|
|
|
stream_put_ospf_metric(s, metric);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area,
|
2018-03-27 21:13:34 +02:00
|
|
|
struct prefix *p, uint32_t metric,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct in_addr id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
int length;
|
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (id.s_addr == 0xffffffff) {
|
|
|
|
/* Maybe Link State ID not available. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type%d]: Link ID not available, can't originate",
|
|
|
|
OSPF_SUMMARY_LSA);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type3]: Create summary-LSA instance");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Create new stream for LSA. */
|
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa_header_set(s, LSA_OPTIONS_GET(area), OSPF_SUMMARY_LSA, id,
|
|
|
|
area->ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set summary-LSA body fields. */
|
|
|
|
ospf_summary_lsa_body_set(s, p, metric);
|
|
|
|
|
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
|
|
|
lsah->length = htons(length);
|
|
|
|
|
|
|
|
/* Create OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2002-12-13 21:15:29 +01:00
|
|
|
new->area = area;
|
2008-11-04 14:37:29 +01:00
|
|
|
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = area->ospf->vrf_id;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Copy LSA to store. */
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate Summary-LSA. */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_summary_lsa_prepare_and_flood(struct prefix_ipv4 *p, uint32_t metric,
|
|
|
|
struct ospf_area *area, struct in_addr id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new summary-LSA instance. */
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!(new = ospf_summary_lsa_new(area, (struct prefix *)p, metric, id)))
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Instlal LSA to LSDB. */
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_lsa_install(area->ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Update LSA origination count. */
|
2003-03-25 06:07:42 +01:00
|
|
|
area->ospf->lsa_originate_count++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flooding new LSA through area. */
|
|
|
|
ospf_flood_through_area(area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Originate summary-LSA %p",
|
|
|
|
new->data->type, &new->data->id,
|
2015-03-03 08:51:53 +01:00
|
|
|
(void *)new);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-03-17 10:17:39 +01:00
|
|
|
static struct ospf_lsa *ospf_handle_summarylsa_lsId_chg(struct ospf_area *area,
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct prefix_ipv4 *p,
|
|
|
|
uint8_t type,
|
|
|
|
uint32_t metric,
|
|
|
|
struct in_addr old_id)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa = NULL;
|
|
|
|
struct ospf_lsa *new = NULL;
|
|
|
|
struct summary_lsa *sl = NULL;
|
|
|
|
struct ospf_area *old_area = NULL;
|
2023-03-17 10:17:39 +01:00
|
|
|
struct ospf *ospf = area->ospf;
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct prefix_ipv4 old_prefix;
|
|
|
|
uint32_t old_metric;
|
|
|
|
struct in_addr mask;
|
|
|
|
uint32_t metric_val;
|
|
|
|
char *metric_buf;
|
|
|
|
|
2023-03-17 10:17:39 +01:00
|
|
|
lsa = ospf_lsdb_lookup_by_id(area->lsdb, type, p->prefix,
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
ospf->router_id);
|
|
|
|
|
|
|
|
if (!lsa) {
|
|
|
|
flog_warn(EC_OSPF_LSA_NULL, "(%s): LSA not found", __func__);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
sl = (struct summary_lsa *)lsa->data;
|
|
|
|
|
|
|
|
old_area = lsa->area;
|
|
|
|
old_metric = GET_METRIC(sl->metric);
|
|
|
|
old_prefix.prefix = sl->header.id;
|
|
|
|
old_prefix.prefixlen = ip_masklen(sl->mask);
|
|
|
|
old_prefix.family = AF_INET;
|
|
|
|
|
|
|
|
|
|
|
|
/* change the mask */
|
|
|
|
masklen2ip(p->prefixlen, &mask);
|
|
|
|
sl->mask.s_addr = mask.s_addr;
|
|
|
|
|
|
|
|
/* Copy the metric*/
|
|
|
|
metric_val = htonl(metric);
|
|
|
|
metric_buf = (char *)&metric_val;
|
|
|
|
memcpy(sl->metric, metric_buf, sizeof(metric_val));
|
|
|
|
|
|
|
|
if (type == OSPF_SUMMARY_LSA) {
|
|
|
|
/*Refresh the LSA with new LSA*/
|
|
|
|
ospf_summary_lsa_refresh(ospf, lsa);
|
|
|
|
|
|
|
|
new = ospf_summary_lsa_prepare_and_flood(
|
|
|
|
&old_prefix, old_metric, old_area, old_id);
|
|
|
|
} else {
|
|
|
|
/*Refresh the LSA with new LSA*/
|
|
|
|
ospf_summary_asbr_lsa_refresh(ospf, lsa);
|
|
|
|
|
|
|
|
new = ospf_asbr_summary_lsa_prepare_and_flood(
|
|
|
|
&old_prefix, old_metric, old_area, old_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate Summary-LSA. */
|
|
|
|
struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p,
|
|
|
|
uint32_t metric,
|
|
|
|
struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct in_addr id;
|
|
|
|
enum lsid_status status;
|
|
|
|
struct ospf_lsa *new = NULL;
|
|
|
|
|
|
|
|
status = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p,
|
|
|
|
&id);
|
|
|
|
|
|
|
|
if (status == LSID_CHANGE) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug("Link ID has to be changed.");
|
|
|
|
|
2023-03-17 10:17:39 +01:00
|
|
|
new = ospf_handle_summarylsa_lsId_chg(area, p, OSPF_SUMMARY_LSA,
|
|
|
|
metric, id);
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
return new;
|
|
|
|
} else if (status == LSID_NOT_AVAILABLE) {
|
|
|
|
/* Link State ID not available. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5]: Link ID not available, can't originate");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new = ospf_summary_lsa_prepare_and_flood(p, metric, area, id);
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct ospf_lsa *ospf_summary_lsa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct summary_lsa *sl;
|
|
|
|
struct prefix p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Sanity check. */
|
|
|
|
assert(lsa->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
sl = (struct summary_lsa *)lsa->data;
|
|
|
|
p.prefixlen = ip_masklen(sl->mask);
|
|
|
|
new = ospf_summary_lsa_new(lsa->area, &p, GET_METRIC(sl->metric),
|
|
|
|
sl->header.id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!new)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_install(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flood LSA through AS. */
|
|
|
|
ospf_flood_through_area(new->area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Debug logging. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: summary-LSA refresh",
|
|
|
|
new->data->type, &new->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* summary-ASBR-LSA related functions. */
|
|
|
|
static void ospf_summary_asbr_lsa_body_set(struct stream *s, struct prefix *p,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* Put Network Mask. */
|
2018-03-27 21:13:34 +02:00
|
|
|
stream_put_ipv4(s, (uint32_t)0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set # TOS. */
|
2018-03-27 21:13:34 +02:00
|
|
|
stream_putc(s, (uint8_t)0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set metric. */
|
|
|
|
stream_put_ospf_metric(s, metric);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area,
|
|
|
|
struct prefix *p,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t metric,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct in_addr id)
|
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
int length;
|
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (id.s_addr == 0xffffffff) {
|
|
|
|
/* Maybe Link State ID not available. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type%d]: Link ID not available, can't originate",
|
|
|
|
OSPF_ASBR_SUMMARY_LSA);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Type3]: Create summary-LSA instance");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Create new stream for LSA. */
|
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa_header_set(s, LSA_OPTIONS_GET(area), OSPF_ASBR_SUMMARY_LSA, id,
|
|
|
|
area->ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Set summary-LSA body fields. */
|
|
|
|
ospf_summary_asbr_lsa_body_set(s, p, metric);
|
|
|
|
|
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
|
|
|
lsah->length = htons(length);
|
|
|
|
|
|
|
|
/* Create OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2002-12-13 21:15:29 +01:00
|
|
|
new->area = area;
|
2008-11-04 14:37:29 +01:00
|
|
|
SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = area->ospf->vrf_id;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Copy LSA to store. */
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate summary-ASBR-LSA. */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_asbr_summary_lsa_prepare_and_flood(struct prefix_ipv4 *p, uint32_t metric,
|
|
|
|
struct ospf_area *area,
|
|
|
|
struct in_addr id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new summary-LSA instance. */
|
|
|
|
new = ospf_summary_asbr_lsa_new(area, (struct prefix *)p, metric, id);
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!new)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Install LSA to LSDB. */
|
|
|
|
new = ospf_lsa_install(area->ospf, NULL, new);
|
|
|
|
|
|
|
|
/* Update LSA origination count. */
|
|
|
|
area->ospf->lsa_originate_count++;
|
|
|
|
|
2004-12-08 19:12:06 +01:00
|
|
|
/* Flooding new LSA through area. */
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_flood_through_area(area, NULL, new);
|
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Originate summary-ASBR-LSA %p",
|
|
|
|
new->data->type, &new->data->id,
|
2015-03-03 08:51:53 +01:00
|
|
|
(void *)new);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p,
|
|
|
|
uint32_t metric,
|
|
|
|
struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct in_addr id;
|
|
|
|
enum lsid_status status;
|
|
|
|
|
|
|
|
status = ospf_lsa_unique_id(area->ospf, area->lsdb,
|
|
|
|
OSPF_ASBR_SUMMARY_LSA, p, &id);
|
|
|
|
|
|
|
|
if (status == LSID_CHANGE) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug("Link ID has to be changed.");
|
|
|
|
|
|
|
|
new = ospf_handle_summarylsa_lsId_chg(
|
2023-03-17 10:17:39 +01:00
|
|
|
area, p, OSPF_ASBR_SUMMARY_LSA, metric, id);
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
return new;
|
|
|
|
} else if (status == LSID_NOT_AVAILABLE) {
|
|
|
|
/* Link State ID not available. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5]: Link ID not available, can't originate");
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
new = ospf_asbr_summary_lsa_prepare_and_flood(p, metric, area, id);
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct ospf_lsa *ospf_summary_asbr_lsa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct summary_lsa *sl;
|
|
|
|
struct prefix p;
|
2022-11-21 13:50:16 +01:00
|
|
|
bool ind_lsa = false;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Sanity check. */
|
|
|
|
assert(lsa->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-11-21 13:50:16 +01:00
|
|
|
if (lsa->area->fr_info.indication_lsa_self &&
|
|
|
|
(lsa->area->fr_info.indication_lsa_self == lsa))
|
|
|
|
ind_lsa = true;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
sl = (struct summary_lsa *)lsa->data;
|
|
|
|
p.prefixlen = ip_masklen(sl->mask);
|
|
|
|
new = ospf_summary_asbr_lsa_new(lsa->area, &p, GET_METRIC(sl->metric),
|
|
|
|
sl->header.id);
|
2005-11-20 15:54:12 +01:00
|
|
|
if (!new)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_install(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flood LSA through area. */
|
|
|
|
ospf_flood_through_area(new->area, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-11-21 13:50:16 +01:00
|
|
|
if (ind_lsa)
|
|
|
|
new->area->fr_info.indication_lsa_self = new;
|
|
|
|
|
2005-11-20 15:54:12 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: summary-ASBR-LSA refresh",
|
|
|
|
new->data->type, &new->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* AS-external-LSA related functions. */
|
|
|
|
|
|
|
|
/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
|
|
|
|
is connected, else 0*/
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct in_addr ospf_external_lsa_nexthop_get(struct ospf *ospf,
|
|
|
|
struct in_addr nexthop)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr fwd;
|
|
|
|
struct prefix nh;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct ospf_interface *oi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
fwd.s_addr = 0;
|
|
|
|
|
|
|
|
if (!nexthop.s_addr)
|
|
|
|
return fwd;
|
|
|
|
|
|
|
|
/* Check whether nexthop is covered by OSPF network. */
|
|
|
|
nh.family = AF_INET;
|
|
|
|
nh.u.prefix4 = nexthop;
|
|
|
|
nh.prefixlen = IPV4_MAX_BITLEN;
|
|
|
|
|
2009-08-03 16:16:41 +02:00
|
|
|
/* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
|
|
|
|
* better to make use of the per-ifp table of ois.
|
|
|
|
*/
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi))
|
|
|
|
if (if_is_operative(oi->ifp))
|
|
|
|
if (oi->address->family == AF_INET)
|
|
|
|
if (prefix_match(oi->address, &nh))
|
|
|
|
return nexthop;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return fwd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NSSA-external-LSA related functions. */
|
|
|
|
|
|
|
|
/* Get 1st IP connection for Forward Addr */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
struct in_addr ospf_get_ip_from_ifp(struct ospf_interface *oi)
|
|
|
|
{
|
|
|
|
struct in_addr fwd;
|
|
|
|
|
2020-02-06 07:49:02 +01:00
|
|
|
fwd.s_addr = INADDR_ANY;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2002-12-13 22:03:13 +01:00
|
|
|
if (if_is_operative(oi->ifp))
|
2002-12-13 21:15:29 +01:00
|
|
|
return oi->address->u.prefix4;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return fwd;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get 1st IP connection for Forward Addr */
|
2002-12-13 22:44:27 +01:00
|
|
|
struct in_addr ospf_get_nssa_ip(struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct in_addr fwd;
|
2002-12-13 22:44:27 +01:00
|
|
|
struct in_addr best_default;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node;
|
|
|
|
struct ospf_interface *oi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
fwd.s_addr = 0;
|
2002-12-13 22:44:27 +01:00
|
|
|
best_default.s_addr = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(area->ospf->oiflist, node, oi)) {
|
2002-12-13 22:03:13 +01:00
|
|
|
if (if_is_operative(oi->ifp))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (oi->area->external_routing == OSPF_AREA_NSSA)
|
2003-03-25 06:07:42 +01:00
|
|
|
if (oi->address
|
|
|
|
&& oi->address->family == AF_INET) {
|
2020-12-14 20:01:31 +01:00
|
|
|
if (best_default.s_addr == INADDR_ANY)
|
2003-03-25 06:07:42 +01:00
|
|
|
best_default =
|
|
|
|
oi->address->u.prefix4;
|
|
|
|
if (oi->area == area)
|
|
|
|
return oi->address->u.prefix4;
|
2002-12-13 22:44:27 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2020-12-14 20:01:31 +01:00
|
|
|
if (best_default.s_addr != INADDR_ANY)
|
2002-12-13 22:44:27 +01:00
|
|
|
return best_default;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-12-14 20:01:31 +01:00
|
|
|
if (best_default.s_addr != INADDR_ANY)
|
2003-03-25 06:07:42 +01:00
|
|
|
return best_default;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return fwd;
|
|
|
|
}
|
2004-06-20 23:00:27 +02:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
int metric_type(struct ospf *ospf, uint8_t src, unsigned short instance)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
struct ospf_redist *red;
|
|
|
|
|
|
|
|
red = ospf_redist_lookup(ospf, src, instance);
|
|
|
|
|
|
|
|
return ((!red || red->dmetric.type < 0) ? DEFAULT_METRIC_TYPE
|
|
|
|
: red->dmetric.type);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
int metric_value(struct ospf *ospf, uint8_t src, unsigned short instance)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
struct ospf_redist *red;
|
|
|
|
|
|
|
|
red = ospf_redist_lookup(ospf, src, instance);
|
|
|
|
if (!red || red->dmetric.value < 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (src == DEFAULT_ROUTE) {
|
2003-03-25 06:07:42 +01:00
|
|
|
if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
|
2002-12-13 21:15:29 +01:00
|
|
|
return DEFAULT_DEFAULT_ORIGINATE_METRIC;
|
|
|
|
else
|
|
|
|
return DEFAULT_DEFAULT_ALWAYS_METRIC;
|
2003-03-25 06:07:42 +01:00
|
|
|
} else if (ospf->default_metric < 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
return DEFAULT_DEFAULT_METRIC;
|
2017-07-17 14:03:14 +02:00
|
|
|
else
|
2003-03-25 06:07:42 +01:00
|
|
|
return ospf->default_metric;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
return red->dmetric.value;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set AS-external-LSA body. */
|
2003-03-25 06:07:42 +01:00
|
|
|
static void ospf_external_lsa_body_set(struct stream *s,
|
|
|
|
struct external_info *ei,
|
|
|
|
struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_ipv4 *p = &ei->p;
|
|
|
|
struct in_addr mask, fwd_addr;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t mvalue;
|
2002-12-13 21:15:29 +01:00
|
|
|
int mtype;
|
|
|
|
int type;
|
2018-03-27 21:13:34 +02:00
|
|
|
unsigned short instance;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Put Network Mask. */
|
|
|
|
masklen2ip(p->prefixlen, &mask);
|
|
|
|
stream_put_ipv4(s, mask.s_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If prefix is default, specify DEFAULT_ROUTE. */
|
2021-07-08 19:09:20 +02:00
|
|
|
type = is_default_prefix4(&ei->p) ? DEFAULT_ROUTE : ei->type;
|
|
|
|
instance = is_default_prefix4(&ei->p) ? 0 : ei->instance;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
mtype = (ROUTEMAP_METRIC_TYPE(ei) != -1)
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
? ROUTEMAP_METRIC_TYPE(ei)
|
|
|
|
: metric_type(ospf, type, instance);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
mvalue = (ROUTEMAP_METRIC(ei) != -1)
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
? ROUTEMAP_METRIC(ei)
|
|
|
|
: metric_value(ospf, type, instance);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Put type of external metric. */
|
|
|
|
stream_putc(s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Put 0 metric. TOS metric is not supported. */
|
|
|
|
stream_put_ospf_metric(s, mvalue);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Get forwarding address to nexthop if on the Connection List, else 0.
|
|
|
|
*/
|
2003-03-25 06:07:42 +01:00
|
|
|
fwd_addr = ospf_external_lsa_nexthop_get(ospf, ei->nexthop);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Put forwarding address. */
|
|
|
|
stream_put_ipv4(s, fwd_addr.s_addr);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-01 20:42:34 +02:00
|
|
|
/* Put route tag */
|
2015-05-20 02:46:33 +02:00
|
|
|
stream_putl(s, ei->tag);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new external-LSA. */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
static struct ospf_lsa *
|
|
|
|
ospf_exnl_lsa_prepare_and_flood(struct ospf *ospf, struct external_info *ei,
|
|
|
|
struct in_addr id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct stream *s;
|
|
|
|
struct lsa_header *lsah;
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
int length;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new stream for LSA. */
|
|
|
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
|
|
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set LSA common header fields. */
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa_header_set(s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA, id,
|
|
|
|
ospf->router_id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set AS-external-LSA body fields. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_external_lsa_body_set(s, ei, ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set length. */
|
|
|
|
length = stream_get_endp(s);
|
|
|
|
lsah->length = htons(length);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Now, create OSPF LSA instance. */
|
2018-08-21 02:41:37 +02:00
|
|
|
new = ospf_lsa_new_and_data(length);
|
2002-12-13 21:15:29 +01:00
|
|
|
new->area = NULL;
|
2008-11-04 14:37:29 +01:00
|
|
|
SET_FLAG(new->flags,
|
|
|
|
OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
|
2017-08-25 22:51:12 +02:00
|
|
|
new->vrf_id = ospf->vrf_id;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Copy LSA data to store, discard stream. */
|
|
|
|
memcpy(new->data, lsah, length);
|
|
|
|
stream_free(s);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
static struct ospf_lsa *ospf_handle_exnl_lsa_lsId_chg(struct ospf *ospf,
|
|
|
|
struct external_info *ei,
|
|
|
|
struct in_addr id)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct as_external_lsa *al;
|
|
|
|
struct in_addr mask;
|
|
|
|
struct ospf_lsa *new;
|
2022-07-27 18:17:50 +02:00
|
|
|
struct external_info ei_summary = {};
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct external_info *ei_old;
|
|
|
|
|
|
|
|
lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, OSPF_AS_EXTERNAL_LSA,
|
|
|
|
ei->p.prefix, ospf->router_id);
|
|
|
|
|
|
|
|
if (!lsa) {
|
|
|
|
flog_warn(EC_OSPF_LSA_NULL, "(%s): LSA not found", __func__);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ei_old = ospf_external_info_check(ospf, lsa);
|
|
|
|
|
|
|
|
al = (struct as_external_lsa *)lsa->data;
|
|
|
|
|
|
|
|
if (!ei_old) {
|
|
|
|
/* eii_old pointer of LSA is NULL, this
|
|
|
|
* must be external aggregate route.
|
|
|
|
*/
|
|
|
|
ei_summary.p.family = AF_INET;
|
|
|
|
ei_summary.p.prefix = al->header.id;
|
|
|
|
ei_summary.p.prefixlen = ip_masklen(al->mask);
|
|
|
|
ei_summary.tag = (unsigned long)ntohl(al->e[0].route_tag);
|
|
|
|
ei_old = &ei_summary;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* change the mask */
|
|
|
|
masklen2ip(ei->p.prefixlen, &mask);
|
|
|
|
al->mask.s_addr = mask.s_addr;
|
|
|
|
|
|
|
|
/*Refresh the LSA with new LSA*/
|
|
|
|
ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, 0);
|
|
|
|
|
|
|
|
/*Originate the old LSA with changed LSID*/
|
|
|
|
new = ospf_exnl_lsa_prepare_and_flood(ospf, ei_old, id);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
|
|
|
|
struct external_info *ei,
|
|
|
|
struct in_addr *old_id)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct in_addr id;
|
|
|
|
enum lsid_status status;
|
|
|
|
|
|
|
|
if (ei == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5]: External info is NULL, can't originate");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug("LSA[Type5]: Originate AS-external-LSA instance");
|
|
|
|
|
|
|
|
/* If old Link State ID is specified, refresh LSA with same ID. */
|
|
|
|
if (old_id)
|
|
|
|
id = *old_id;
|
|
|
|
/* Get Link State with unique ID. */
|
|
|
|
else {
|
|
|
|
status = ospf_lsa_unique_id(ospf, ospf->lsdb,
|
|
|
|
OSPF_AS_EXTERNAL_LSA, &ei->p, &id);
|
|
|
|
|
|
|
|
if (status == LSID_CHANGE) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug("Link ID has to be changed.");
|
|
|
|
|
|
|
|
new = ospf_handle_exnl_lsa_lsId_chg(ospf, ei, id);
|
|
|
|
return new;
|
|
|
|
} else if (status == LSID_NOT_AVAILABLE) {
|
|
|
|
/* Link State ID not available. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5]: Link ID not available, can't originate");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
new = ospf_exnl_lsa_prepare_and_flood(ospf, ei, id);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* As Type-7 */
|
2003-03-25 06:07:42 +01:00
|
|
|
static void ospf_install_flood_nssa(struct ospf *ospf, struct ospf_lsa *lsa,
|
|
|
|
struct external_info *ei)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_lsa *new;
|
2003-03-25 06:07:42 +01:00
|
|
|
struct as_external_lsa *extlsa;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct listnode *node, *nnode;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* LSA may be a Type-5 originated via translation of a Type-7 LSA
|
|
|
|
* which originated from an NSSA area. In which case it should not be
|
|
|
|
* flooded back to NSSA areas.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* NSSA Originate or Refresh (If anyNSSA)
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
LSA is self-originated. And just installed as Type-5.
|
|
|
|
Additionally, install as Type-7 LSDB for every attached NSSA.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
P-Bit controls which ABR performs translation to outside world; If
|
|
|
|
we are an ABR....do not set the P-bit, because we send the Type-5,
|
|
|
|
not as the ABR Translator, but as the ASBR owner within the AS!
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
|
|
|
|
elected ABR Translator will see the P-bit, Translate, and re-flood.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
|
|
|
|
Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
|
2003-07-03 10:36:02 +02:00
|
|
|
/* Don't install Type-7 LSA's into nonNSSA area */
|
|
|
|
if (area->external_routing != OSPF_AREA_NSSA)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* make lsa duplicate, lock=1 */
|
2003-07-12 23:30:57 +02:00
|
|
|
new = ospf_lsa_dup(lsa);
|
|
|
|
new->area = area;
|
|
|
|
new->data->type = OSPF_AS_NSSA_LSA;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* set P-bit if not ABR */
|
2003-04-04 04:44:16 +02:00
|
|
|
if (!IS_OSPF_ABR(ospf)) {
|
2003-07-12 23:30:57 +02:00
|
|
|
SET_FLAG(new->data->options, OSPF_OPTION_NP);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* set non-zero FWD ADDR
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
draft-ietf-ospf-nssa-update-09.txt
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
if the network between the NSSA AS boundary router and
|
|
|
|
the
|
|
|
|
adjacent AS is advertised into OSPF as an internal OSPF
|
|
|
|
route,
|
|
|
|
the forwarding address should be the next op address as
|
|
|
|
is cu
|
|
|
|
currently done with type-5 LSAs. If the intervening
|
|
|
|
network is
|
|
|
|
not adversited into OSPF as an internal OSPF route and
|
|
|
|
the
|
|
|
|
type-7 LSA's P-bit is set a forwarding address should be
|
2017-09-18 00:44:39 +02:00
|
|
|
selected from one of the router's active OSPF interface
|
2003-03-25 06:07:42 +01:00
|
|
|
addresses
|
|
|
|
which belong to the NSSA. If no such addresses exist,
|
|
|
|
then
|
|
|
|
no type-7 LSA's with the P-bit set should originate from
|
|
|
|
this
|
|
|
|
router. */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* kevinm: not updating lsa anymore, just new */
|
|
|
|
extlsa = (struct as_external_lsa *)(new->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-12-14 20:01:31 +01:00
|
|
|
if (extlsa->e[0].fwd_addr.s_addr == INADDR_ANY)
|
2003-03-25 06:07:42 +01:00
|
|
|
extlsa->e[0].fwd_addr = ospf_get_nssa_ip(
|
|
|
|
area); /* this NSSA area in ifp */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-12-14 20:01:31 +01:00
|
|
|
if (extlsa->e[0].fwd_addr.s_addr == INADDR_ANY) {
|
2003-05-16 19:31:51 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type-7]: Could not build FWD-ADDR");
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_discard(new);
|
2003-05-16 19:31:51 +02:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2003-05-16 19:31:51 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* install also as Type-7 */
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_lsa_install(ospf, NULL,
|
|
|
|
new); /* Remove Old, Lock New = 2 */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
/* will send each copy, lock=2+n */
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_flood_through_as(
|
|
|
|
ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *type7)
|
|
|
|
{
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct as_external_lsa *ext, *extnew;
|
|
|
|
struct external_info ei;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
ext = (struct as_external_lsa *)(type7->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* need external_info struct, fill in bare minimum */
|
|
|
|
ei.p.family = AF_INET;
|
|
|
|
ei.p.prefix = type7->data->id;
|
|
|
|
ei.p.prefixlen = ip_masklen(ext->mask);
|
|
|
|
ei.type = ZEBRA_ROUTE_OSPF;
|
|
|
|
ei.nexthop = ext->header.adv_router;
|
|
|
|
ei.route_map_set.metric = -1;
|
|
|
|
ei.route_map_set.metric_type = -1;
|
|
|
|
ei.tag = 0;
|
2018-04-11 18:26:57 +02:00
|
|
|
ei.instance = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if ((new = ospf_external_lsa_new(ospf, &ei, &type7->data->id))
|
|
|
|
== NULL) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-11-02 09:30:20 +01:00
|
|
|
"%s: Could not originate Translated Type-5 for %pI4",
|
|
|
|
__func__, &ei.p.prefix);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
extnew = (struct as_external_lsa *)(new->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* copy over Type-7 data to new */
|
|
|
|
extnew->e[0].tos = ext->e[0].tos;
|
|
|
|
extnew->e[0].route_tag = ext->e[0].route_tag;
|
2020-11-02 15:28:52 +01:00
|
|
|
if (type7->area->suppress_fa) {
|
|
|
|
extnew->e[0].fwd_addr.s_addr = 0;
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("%s: Suppress forwarding address for %pI4",
|
|
|
|
__func__, &ei.p.prefix);
|
2020-11-02 15:28:52 +01:00
|
|
|
} else
|
|
|
|
extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
|
2003-07-12 23:30:57 +02:00
|
|
|
new->data->ls_seqnum = type7->data->ls_seqnum;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* add translated flag, checksum and lock new lsa */
|
|
|
|
SET_FLAG(new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
|
|
|
|
new = ospf_lsa_lock(new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
|
|
|
|
struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
2020-11-02 15:28:52 +01:00
|
|
|
struct ospf_lsa *type7,
|
|
|
|
struct ospf_lsa *type5)
|
2003-07-12 23:30:57 +02:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
|
|
|
struct as_external_lsa *extnew;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-05-31 15:27:51 +02:00
|
|
|
if (ospf->gr_info.restart_in_progress) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Translated Type5]: Graceful Restart in progress, don't originate");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* we cant use ospf_external_lsa_originate() as we need to set
|
|
|
|
* the OSPF_LSA_LOCAL_XLT flag, must originate by hand
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-11-02 09:30:20 +01:00
|
|
|
"%s: Could not translate Type-7, Id %pI4, to Type-5",
|
|
|
|
__func__, &type7->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-10 21:20:44 +02:00
|
|
|
extnew = (struct as_external_lsa *)new->data;
|
|
|
|
|
2020-11-02 15:28:52 +01:00
|
|
|
/* Update LSA sequence number from translated Type-5 LSA */
|
|
|
|
if (type5)
|
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(type5);
|
|
|
|
|
2020-09-10 21:20:44 +02:00
|
|
|
if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
|
2020-11-02 09:30:20 +01:00
|
|
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"%s: Could not install LSA id %pI4", __func__,
|
|
|
|
&type7->data->id);
|
2020-09-10 21:20:44 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF_NSSA) {
|
2020-11-02 09:30:20 +01:00
|
|
|
zlog_debug("%s: translated Type 7, installed", __func__);
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_lsa_header_dump(new->data);
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(" Network mask: %d", ip_masklen(extnew->mask));
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug(" Forward addr: %pI4",
|
|
|
|
&extnew->e[0].fwd_addr);
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf->lsa_originate_count++;
|
|
|
|
ospf_flood_through_as(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh Translated from NSSA AS-external-LSA. */
|
|
|
|
struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *type7,
|
|
|
|
struct ospf_lsa *type5)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *new = NULL;
|
2020-11-02 15:28:52 +01:00
|
|
|
struct as_external_lsa *extold = NULL;
|
|
|
|
uint32_t ls_seqnum = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Sanity checks. */
|
|
|
|
assert(type7 || type5);
|
2006-05-13 01:15:30 +02:00
|
|
|
if (!(type7 || type5))
|
2006-05-13 01:11:14 +02:00
|
|
|
return NULL;
|
2003-07-12 23:30:57 +02:00
|
|
|
if (type7)
|
|
|
|
assert(type7->data);
|
|
|
|
if (type5)
|
|
|
|
assert(type5->data);
|
|
|
|
assert(ospf->anyNSSA);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* get required data according to what has been given */
|
|
|
|
if (type7 && type5 == NULL) {
|
|
|
|
/* find the translated Type-5 for this Type-7 */
|
|
|
|
struct as_external_lsa *ext =
|
|
|
|
(struct as_external_lsa *)(type7->data);
|
|
|
|
struct prefix_ipv4 p = {
|
|
|
|
.prefix = type7->data->id,
|
|
|
|
.prefixlen = ip_masklen(ext->mask),
|
|
|
|
.family = AF_INET,
|
|
|
|
};
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
type5 = ospf_external_info_find_lsa(ospf, &p);
|
|
|
|
} else if (type5 && type7 == NULL) {
|
|
|
|
/* find the type-7 from which supplied type-5 was translated,
|
|
|
|
* ie find first type-7 with same LSA Id.
|
|
|
|
*/
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *ln, *lnn;
|
2003-07-12 23:30:57 +02:00
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct ospf_area *area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, ln, lnn, area)) {
|
2003-07-12 23:30:57 +02:00
|
|
|
if (area->external_routing != OSPF_AREA_NSSA && !type7)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-01-17 19:28:17 +01:00
|
|
|
LSDB_LOOP (NSSA_LSDB(area), rn, lsa) {
|
2003-07-12 23:30:57 +02:00
|
|
|
if (lsa->data->id.s_addr
|
|
|
|
== type5->data->id.s_addr) {
|
|
|
|
type7 = lsa;
|
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* do we have type7? */
|
|
|
|
if (!type7) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("%s: no Type-7 found for Type-5 LSA Id %pI4",
|
|
|
|
__func__, &type5->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* do we have valid translated type5? */
|
|
|
|
if (type5 == NULL || !CHECK_FLAG(type5->flags, OSPF_LSA_LOCAL_XLT)) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2022-08-24 19:56:16 +02:00
|
|
|
"%s: No translated Type-5 found for Type-7 with Id %pI4",
|
|
|
|
__func__, &type7->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-02 15:28:52 +01:00
|
|
|
extold = (struct as_external_lsa *)type5->data;
|
|
|
|
if (type7->area->suppress_fa == 1) {
|
|
|
|
if (extold->e[0].fwd_addr.s_addr == 0)
|
|
|
|
ls_seqnum = ntohl(type5->data->ls_seqnum);
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Delete LSA from neighbor retransmit-list. */
|
|
|
|
ospf_ls_retransmit_delete_nbr_as(ospf, type5);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* create new translated LSA */
|
|
|
|
if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF_NSSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2022-08-24 19:56:16 +02:00
|
|
|
"%s: Could not translate Type-7 for %pI4 to Type-5",
|
|
|
|
__func__, &type7->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-02 15:28:52 +01:00
|
|
|
if (type7->area->suppress_fa == 1) {
|
|
|
|
if (extold->e[0].fwd_addr.s_addr == 0)
|
|
|
|
new->data->ls_seqnum = htonl(ls_seqnum + 1);
|
|
|
|
}
|
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (!(new = ospf_lsa_install(ospf, NULL, new))) {
|
2022-08-24 19:56:16 +02:00
|
|
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"%s: Could not install translated LSA, Id %pI4",
|
|
|
|
__func__, &type7->data->id);
|
2003-07-12 23:30:57 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Flood LSA through area. */
|
|
|
|
ospf_flood_through_as(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
return new;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Originate an AS-external-LSA, install and flood. */
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
|
|
|
struct external_info *ei)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-05-31 15:27:51 +02:00
|
|
|
if (ospf->gr_info.restart_in_progress) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5]: Graceful Restart in progress, don't originate");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Added for NSSA project....
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
External LSAs are originated in ASBRs as usual, but for NSSA
|
|
|
|
systems.
|
|
|
|
there is the global Type-5 LSDB and a Type-7 LSDB installed for
|
|
|
|
every area. The Type-7's are flooded to every IR and every ABR; We
|
|
|
|
install the Type-5 LSDB so that the normal "refresh" code operates
|
|
|
|
as usual, and flag them as not used during ASE calculations. The
|
|
|
|
Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
|
|
|
|
Address of non-zero.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
If an ABR is the elected NSSA translator, following SPF and during
|
|
|
|
the ABR task it will translate all the scanned Type-7's, with P-bit
|
|
|
|
ON and not-self generated, and translate to Type-5's throughout the
|
|
|
|
non-NSSA/STUB AS.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
A difference in operation depends whether this ASBR is an ABR
|
|
|
|
or not. If not an ABR, the P-bit is ON, to indicate that any
|
|
|
|
elected NSSA-ABR can perform its translation.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
If an ABR, the P-bit is OFF; No ABR will perform translation and
|
|
|
|
this ASBR will flood the Type-5 LSA as usual.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
For the case where this ASBR is not an ABR, the ASE calculations
|
|
|
|
are based on the Type-5 LSDB; The Type-7 LSDB exists just to
|
|
|
|
demonstrate to the user that there are LSA's that belong to any
|
|
|
|
attached NSSA.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
Finally, it just so happens that when the ABR is translating every
|
|
|
|
Type-7 into Type-5, it installs it into the Type-5 LSDB as an
|
|
|
|
approved Type-5 (translated from Type-7); at the end of translation
|
|
|
|
if any Translated Type-5's remain unapproved, then they must be
|
|
|
|
flushed from the AS.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-06 07:49:02 +01:00
|
|
|
if (ospf->router_id.s_addr == INADDR_ANY) {
|
2022-11-07 11:03:41 +01:00
|
|
|
if (ei && IS_DEBUG_OSPF_EVENT)
|
2020-02-06 07:49:02 +01:00
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5:%pI4]: deferring AS-external-LSA origination, router ID is zero",
|
|
|
|
&ei->p.prefix);
|
2019-07-29 14:44:44 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new AS-external-LSA instance. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) {
|
2022-11-07 11:03:41 +01:00
|
|
|
if (ei && IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type5:%pI4]: Could not originate AS-external-LSA",
|
|
|
|
&ei->p.prefix);
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Install newly created LSA into Type-5 LSDB, lock = 1. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_install(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Update LSA origination count. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->lsa_originate_count++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flooding new LSA. only to AS (non-NSSA/STUB) */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_flood_through_as(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If there is any attached NSSA, do special handling */
|
2003-07-12 23:30:57 +02:00
|
|
|
if (ospf->anyNSSA &&
|
|
|
|
/* stay away from translated LSAs! */
|
|
|
|
!(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_install_flood_nssa(
|
|
|
|
ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Debug logging. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Originate AS-external-LSA %p",
|
|
|
|
new->data->type, &new->data->id,
|
2015-03-03 08:51:53 +01:00
|
|
|
(void *)new);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2003-04-04 04:44:16 +02:00
|
|
|
static struct external_info *ospf_default_external_info(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int type;
|
|
|
|
struct prefix_ipv4 p;
|
2020-05-03 11:25:55 +02:00
|
|
|
struct external_info *default_ei;
|
|
|
|
int ret = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefix.s_addr = 0;
|
|
|
|
p.prefixlen = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Get `default-information originate` working for ospf instances
The ospf instance code is not properly handling the default route
when using default-information originate. This is because
the code is looking for the default route to be saved with an
instance of <ospf instance id> but we always save it as a instance
id of 0. In fact OSPF asks zebra for the default route as a special
case in instance 0, always.
Here is the correct behavior:
eva# show ip ospf data
OSPF Instance: 3
OSPF Router with ID (192.168.122.1)
AS External Link States
Link ID ADV Router Age Seq# CkSum Route
0.0.0.0 192.168.122.1 8 0x80000001 0xdb08 E2 0.0.0.0/0 [0x0]
eva# show ip route
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:02:03
Fixes: #10251
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2022-01-03 18:15:02 +01:00
|
|
|
default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE, 0, &p);
|
2020-05-03 11:25:55 +02:00
|
|
|
if (!default_ei)
|
|
|
|
return NULL;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* First, lookup redistributed default route. */
|
|
|
|
for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
struct list *ext_list;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
if (type == ZEBRA_ROUTE_OSPF)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 02:21:03 +01:00
|
|
|
ext_list = ospf->external[type];
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
if (!ext_list)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-05-03 11:25:55 +02:00
|
|
|
ret = ospf_external_default_routemap_apply_walk(ospf, ext_list,
|
|
|
|
default_ei);
|
|
|
|
if (ret)
|
|
|
|
return default_ei;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
void ospf_external_lsa_rid_change(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct external_info *ei;
|
2020-09-05 17:15:51 +02:00
|
|
|
struct ospf_external_aggr_rt *aggr;
|
2021-04-25 07:40:33 +02:00
|
|
|
struct ospf_lsa *lsa = NULL;
|
|
|
|
int force;
|
2019-07-29 12:27:25 +02:00
|
|
|
int type;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_table *rt;
|
|
|
|
struct list *ext_list;
|
|
|
|
struct listnode *node;
|
|
|
|
struct ospf_external *ext;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
ext_list = ospf->external[type];
|
|
|
|
if (!ext_list)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
|
|
|
|
/* Originate As-external-LSA from all type of
|
|
|
|
* distribute source.
|
|
|
|
*/
|
|
|
|
rt = ext->external_info;
|
|
|
|
if (!rt)
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
for (rn = route_top(rt); rn; rn = route_next(rn)) {
|
|
|
|
ei = rn->info;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 12:27:25 +02:00
|
|
|
if (!ei)
|
|
|
|
continue;
|
|
|
|
|
2021-07-08 19:09:20 +02:00
|
|
|
if (is_default_prefix4(&ei->p))
|
2019-07-29 12:27:25 +02:00
|
|
|
continue;
|
|
|
|
|
2021-04-25 07:40:33 +02:00
|
|
|
lsa = ospf_external_info_find_lsa(ospf, &ei->p);
|
2020-09-05 17:15:51 +02:00
|
|
|
|
|
|
|
aggr = ospf_external_aggr_match(ospf, &ei->p);
|
|
|
|
if (aggr) {
|
2021-04-25 07:40:33 +02:00
|
|
|
|
|
|
|
if (!ospf_redistribute_check(ospf, ei,
|
|
|
|
NULL))
|
|
|
|
continue;
|
|
|
|
|
2020-09-05 17:15:51 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
|
|
|
|
zlog_debug(
|
|
|
|
"Originate Summary LSA after reset/router-ID change");
|
2021-04-25 07:40:33 +02:00
|
|
|
|
2020-09-05 17:15:51 +02:00
|
|
|
/* Here the LSA is originated as new */
|
|
|
|
ospf_originate_summary_lsa(ospf, aggr,
|
|
|
|
ei);
|
2021-04-25 07:40:33 +02:00
|
|
|
} else if (lsa) {
|
|
|
|
/* LSA needs to be refreshed even if
|
|
|
|
* there is no change in the route
|
|
|
|
* params if the LSA is in maxage.
|
|
|
|
*/
|
|
|
|
if (IS_LSA_MAXAGE(lsa))
|
|
|
|
force = LSA_REFRESH_FORCE;
|
|
|
|
else
|
|
|
|
force = LSA_REFRESH_IF_CHANGED;
|
|
|
|
|
|
|
|
ospf_external_lsa_refresh(ospf, lsa,
|
|
|
|
ei, force, 0);
|
|
|
|
} else {
|
|
|
|
if (!ospf_redistribute_check(ospf, ei,
|
|
|
|
NULL))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!ospf_external_lsa_originate(ospf,
|
2022-02-24 18:33:08 +01:00
|
|
|
ei))
|
2021-04-25 07:40:33 +02:00
|
|
|
flog_warn(
|
|
|
|
EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"LSA: AS-external-LSA was not originated.");
|
|
|
|
}
|
2019-07-29 12:27:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ei = ospf_default_external_info(ospf);
|
|
|
|
if (ei && !ospf_external_lsa_originate(ospf, ei)) {
|
|
|
|
flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
|
|
|
|
"LSA: AS-external-LSA for default route was not originated.");
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2003-04-13 23:42:11 +02:00
|
|
|
/* Flush any NSSA LSAs for given prefix */
|
|
|
|
void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2017-08-25 22:51:12 +02:00
|
|
|
struct ospf_lsa *lsa = NULL;
|
2003-04-13 23:42:11 +02:00
|
|
|
struct ospf_area *area;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
|
|
|
|
if (area->external_routing == OSPF_AREA_NSSA) {
|
2017-08-25 22:51:12 +02:00
|
|
|
lsa = ospf_lsa_lookup(ospf, area, OSPF_AS_NSSA_LSA,
|
|
|
|
p->prefix, ospf->router_id);
|
|
|
|
if (!lsa) {
|
2003-05-16 19:31:51 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"LSA: There is no such AS-NSSA-LSA %pFX in LSDB",
|
|
|
|
p);
|
2003-05-16 19:31:51 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ospf_ls_retransmit_delete_nbr_area(area, lsa);
|
|
|
|
if (!IS_LSA_MAXAGE(lsa)) {
|
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
|
|
|
ospf_lsa_flush_area(lsa, area);
|
|
|
|
}
|
|
|
|
}
|
2003-04-13 23:42:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flush an AS-external-LSA from LSDB and routing domain. */
|
2018-03-27 21:13:34 +02:00
|
|
|
void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type,
|
2003-03-25 06:07:42 +01:00
|
|
|
struct prefix_ipv4 *p,
|
2016-01-18 11:12:10 +01:00
|
|
|
ifindex_t ifindex /*, struct in_addr nexthop */)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2020-10-14 19:17:14 +02:00
|
|
|
zlog_debug("LSA: Flushing AS-external-LSA %pFX", p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* First lookup LSA from LSDB. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (!(lsa = ospf_external_info_find_lsa(ospf, p))) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-14 19:17:14 +02:00
|
|
|
"LSA: There is no such AS-external-LSA %pFX in LSDB",
|
|
|
|
p);
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* If LSA is selforiginated, not a translated LSA, and there is
|
|
|
|
* NSSA area, flush Type-7 LSA's at first.
|
|
|
|
*/
|
|
|
|
if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
|
|
|
|
&& !(CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)))
|
2003-05-16 19:31:51 +02:00
|
|
|
ospf_nssa_lsa_flush(ospf, p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!IS_LSA_MAXAGE(lsa)) {
|
2022-03-21 10:48:46 +01:00
|
|
|
/* Sweep LSA from Link State Retransmit List. */
|
|
|
|
ospf_ls_retransmit_delete_nbr_as(ospf, lsa);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Unregister LSA from Refresh queue. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flush AS-external-LSA through AS. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_flush_as(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("%s: stop", __func__);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_external_lsa_refresh_default(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
struct external_info *ei;
|
|
|
|
struct ospf_lsa *lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = 0;
|
2020-02-06 07:49:02 +01:00
|
|
|
p.prefix.s_addr = INADDR_ANY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-04-04 04:44:16 +02:00
|
|
|
ei = ospf_default_external_info(ospf);
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa = ospf_external_info_find_lsa(ospf, &p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-07-29 14:46:05 +02:00
|
|
|
if (ei && lsa) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
|
2020-08-15 11:55:40 +02:00
|
|
|
(void *)lsa);
|
|
|
|
ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE,
|
|
|
|
false);
|
2019-07-29 14:46:05 +02:00
|
|
|
} else if (ei && !lsa) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
|
|
|
|
ospf_external_lsa_originate(ospf, ei);
|
|
|
|
} else if (lsa) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
|
|
|
|
ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &p, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type,
|
|
|
|
unsigned short instance, int force)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct external_info *ei;
|
Multi-Instance OSPF Summary
——————————————-------------
- etc/init.d/quagga is modified to support creating separate ospf daemon
process for each instance. Each individual instance is monitored by
watchquagga just like any protocol daemons.(requires initd-mi.patch).
- Vtysh is modified to able to connect to multiple daemons of the same
protocol (supported for OSPF only for now).
- ospfd is modified to remember the Instance-ID that its invoked with. For
the entire life of the process it caters to any command request that
matches that instance-ID (unless its a non instance specific command).
Routes/messages to zebra are tagged with instance-ID.
- zebra route/redistribute mechanisms are modified to work with
[protocol type + instance-id]
- bgpd now has ability to have multiple instance specific redistribution
for a protocol (OSPF only supported/tested for now).
- zlog ability to display instance-id besides the protocol/daemon name.
- Changes in other daemons are to because of the needed integration with
some of the modified APIs/routines. (Didn’t prefer replicating too many
separate instance specific APIs.)
- config/show/debug commands are modified to take instance-id argument
as appropriate.
Guidelines to start using multi-instance ospf
---------------------------------------------
The patch is backward compatible, i.e for any previous way of single ospf
deamon(router ospf <cr>) will continue to work as is, including all the
show commands etc.
To enable multiple instances, do the following:
1. service quagga stop
2. Modify /etc/quagga/daemons to add instance-ids of each desired
instance in the following format:
ospfd=“yes"
ospfd_instances="1,2,3"
assuming you want to enable 3 instances with those instance ids.
3. Create corresponding ospfd config files as ospfd-1.conf, ospfd-2.conf
and ospfd-3.conf.
4. service quagga start/restart
5. Verify that the deamons are started as expected. You should see
ospfd started with -n <instance-id> option.
ps –ef | grep quagga
With that /var/run/quagga/ should have ospfd-<instance-id>.pid and
ospfd-<instance-id>/vty to each instance.
6. vtysh to work with instances as you would with any other deamons.
7. Overall most quagga semantics are the same working with the instance
deamon, like it is for any other daemon.
NOTE:
To safeguard against errors leading to too many processes getting invoked,
a hard limit on number of instance-ids is in place, currently its 5.
Allowed instance-id range is <1-65535>
Once daemons are up, show running from vtysh should show the instance-id
of each daemon as 'router ospf <instance-id>’ (without needing explicit
configuration)
Instance-id can not be changed via vtysh, other router ospf configuration
is allowed as before.
Signed-off-by: Vipin Kumar <vipin@cumulusnetworks.com>
Reviewed-by: Daniel Walton <dwalton@cumulusnetworks.com>
Reviewed-by: Dinesh G Dutt <ddutt@cumulusnetworks.com>
2015-05-20 03:03:42 +02:00
|
|
|
struct ospf_external *ext;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-21 02:21:03 +01:00
|
|
|
if (type == DEFAULT_ROUTE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ext = ospf_external_lookup(ospf, type, instance);
|
|
|
|
|
|
|
|
if (ext && EXTERNAL_INFO(ext)) {
|
|
|
|
/* Refresh each redistributed AS-external-LSAs. */
|
|
|
|
for (rn = route_top(EXTERNAL_INFO(ext)); rn;
|
|
|
|
rn = route_next(rn)) {
|
|
|
|
ei = rn->info;
|
|
|
|
if (ei) {
|
2021-07-08 19:09:20 +02:00
|
|
|
if (!is_default_prefix4(&ei->p)) {
|
2017-11-21 02:21:03 +01:00
|
|
|
struct ospf_lsa *lsa;
|
2020-09-05 17:15:51 +02:00
|
|
|
struct ospf_external_aggr_rt *aggr;
|
2017-11-21 02:21:03 +01:00
|
|
|
|
2020-09-05 17:15:51 +02:00
|
|
|
aggr = ospf_external_aggr_match(ospf,
|
|
|
|
&ei->p);
|
2017-11-21 02:21:03 +01:00
|
|
|
lsa = ospf_external_info_find_lsa(
|
2020-09-05 17:15:51 +02:00
|
|
|
ospf, &ei->p);
|
|
|
|
if (aggr) {
|
|
|
|
/* Check the AS-external-LSA
|
|
|
|
* should be originated.
|
|
|
|
*/
|
|
|
|
if (!ospf_redistribute_check(
|
|
|
|
ospf, ei, NULL)) {
|
|
|
|
|
|
|
|
ospf_unlink_ei_from_aggr(
|
|
|
|
ospf, aggr, ei);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(
|
|
|
|
lsa,
|
|
|
|
EXTNL_LSA_AGGR))
|
|
|
|
zlog_debug(
|
2021-02-16 00:46:48 +01:00
|
|
|
"%s: Send Aggreate LSA (%pFX)",
|
2020-09-05 17:15:51 +02:00
|
|
|
__func__,
|
2021-02-16 00:46:48 +01:00
|
|
|
&aggr->p);
|
2020-09-05 17:15:51 +02:00
|
|
|
|
|
|
|
ospf_originate_summary_lsa(
|
|
|
|
ospf, aggr, ei);
|
|
|
|
|
|
|
|
} else if (lsa) {
|
|
|
|
|
|
|
|
if (IS_LSA_MAXAGE(lsa))
|
|
|
|
force = LSA_REFRESH_FORCE;
|
|
|
|
|
2017-11-21 02:21:03 +01:00
|
|
|
ospf_external_lsa_refresh(
|
2020-08-15 11:55:40 +02:00
|
|
|
ospf, lsa, ei, force,
|
|
|
|
false);
|
2020-09-05 17:15:51 +02:00
|
|
|
} else {
|
|
|
|
if (!ospf_redistribute_check(
|
|
|
|
ospf, ei, NULL))
|
|
|
|
continue;
|
2017-11-21 02:21:03 +01:00
|
|
|
ospf_external_lsa_originate(
|
|
|
|
ospf, ei);
|
2020-09-05 17:15:51 +02:00
|
|
|
}
|
2017-11-21 02:21:03 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Refresh AS-external-LSA. */
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa,
|
2020-08-15 11:55:40 +02:00
|
|
|
struct external_info *ei, int force,
|
|
|
|
bool is_aggr)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new;
|
2020-08-15 11:55:40 +02:00
|
|
|
int changed = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check the AS-external-LSA should be originated. */
|
2020-08-15 11:55:40 +02:00
|
|
|
if (!is_aggr)
|
|
|
|
if (!ospf_redistribute_check(ospf, ei, &changed)) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
2020-12-14 23:01:18 +01:00
|
|
|
"LSA[Type%d:%pI4] Could not be refreshed, redist check fail",
|
2020-08-15 11:55:40 +02:00
|
|
|
lsa->data->type,
|
2020-12-14 23:01:18 +01:00
|
|
|
&lsa->data->id);
|
2020-08-15 11:55:40 +02:00
|
|
|
|
|
|
|
ospf_external_lsa_flush(ospf, ei->type, &ei->p,
|
|
|
|
ei->ifindex /*, ei->nexthop */);
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!changed && !force) {
|
2003-07-12 23:30:57 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Not refreshed, not changed/forced",
|
|
|
|
lsa->data->type, &lsa->data->id);
|
2010-01-24 23:42:13 +01:00
|
|
|
return NULL;
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Delete LSA from neighbor retransmit-list. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ls_retransmit_delete_nbr_as(ospf, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Unregister AS-external-LSA from refresh-list. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_external_lsa_new(ospf, ei, &lsa->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (new == NULL) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Could not be refreshed",
|
|
|
|
lsa->data->type, &lsa->data->id);
|
2010-01-24 23:42:13 +01:00
|
|
|
return NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_install(ospf, NULL, new); /* As type-5. */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Flood LSA through AS. */
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_flood_through_as(ospf, NULL, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
|
2003-07-12 23:30:57 +02:00
|
|
|
if (ospf->anyNSSA && !(CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT)))
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_install_flood_nssa(ospf, new,
|
|
|
|
ei); /* Install/Flood per new rules */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Register self-originated LSA to refresh queue.
|
|
|
|
* Translated LSAs should not be registered, but refreshed upon
|
|
|
|
* refresh of the Type-7
|
|
|
|
*/
|
|
|
|
if (!CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT))
|
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Debug logging. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: AS-external-LSA refresh",
|
|
|
|
new->data->type, &new->data->id);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_header_dump(new->data);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
return new;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSA installation functions. */
|
|
|
|
|
|
|
|
/* Install router-LSA to an area. */
|
2005-05-06 23:37:42 +02:00
|
|
|
static struct ospf_lsa *
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_router_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_area *area = new->area;
|
|
|
|
|
|
|
|
/* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
|
|
|
|
The entire routing table must be recalculated, starting with
|
|
|
|
the shortest path calculations for each area (not just the
|
|
|
|
area whose link-state database has changed).
|
|
|
|
*/
|
|
|
|
|
2009-07-27 12:42:35 +02:00
|
|
|
if (IS_LSA_SELF(new)) {
|
|
|
|
|
|
|
|
/* Only install LSA if it is originated/refreshed by us.
|
|
|
|
* If LSA was received by flooding, the RECEIVED flag is set so
|
|
|
|
* do
|
|
|
|
* not link the LSA */
|
|
|
|
if (CHECK_FLAG(new->flags, OSPF_LSA_RECEIVED))
|
|
|
|
return new; /* ignore stale LSA */
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set self-originated router-LSA. */
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&area->router_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
area->router_lsa_self = ospf_lsa_lock(new);
|
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2009-07-27 12:42:35 +02:00
|
|
|
if (rt_recalc)
|
2014-10-09 15:19:51 +02:00
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_ROUTER_LSA_INSTALL);
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install network-LSA to an area. */
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct ospf_lsa *ospf_network_lsa_install(struct ospf *ospf,
|
|
|
|
struct ospf_interface *oi,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *new,
|
|
|
|
int rt_recalc)
|
|
|
|
{
|
2023-01-17 17:09:55 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
|
|
|
|
The entire routing table must be recalculated, starting with
|
|
|
|
the shortest path calculations for each area (not just the
|
|
|
|
area whose link-state database has changed).
|
|
|
|
*/
|
2009-07-27 12:42:35 +02:00
|
|
|
if (IS_LSA_SELF(new)) {
|
|
|
|
/* We supposed that when LSA is originated by us, we pass the
|
|
|
|
int
|
|
|
|
for which it was originated. If LSA was received by flooding,
|
|
|
|
the RECEIVED flag is set, so we do not link the LSA to the
|
|
|
|
int. */
|
|
|
|
if (CHECK_FLAG(new->flags, OSPF_LSA_RECEIVED))
|
|
|
|
return new; /* ignore stale LSA */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&oi->network_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
oi->network_lsa_self = ospf_lsa_lock(new);
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2009-07-27 12:42:35 +02:00
|
|
|
if (rt_recalc)
|
2014-10-09 15:19:51 +02:00
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_NETWORK_LSA_INSTALL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install summary-LSA to an area. */
|
2005-05-06 23:37:42 +02:00
|
|
|
static struct ospf_lsa *
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_summary_lsa_install(struct ospf *ospf, struct ospf_lsa *new, int rt_recalc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (rt_recalc && !IS_LSA_SELF(new)) {
|
|
|
|
/* RFC 2328 Section 13.2 Summary-LSAs
|
|
|
|
The best route to the destination described by the summary-
|
|
|
|
LSA must be recalculated (see Section 16.5). If this
|
|
|
|
destination is an AS boundary router, it may also be
|
|
|
|
necessary to re-examine all the AS-external-LSAs.
|
|
|
|
*/
|
|
|
|
|
2014-10-09 15:19:51 +02:00
|
|
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_SUMMARY_LSA_INSTALL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_LSA_SELF(new))
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install ASBR-summary-LSA to an area. */
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct ospf_lsa *ospf_summary_asbr_lsa_install(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *new,
|
|
|
|
int rt_recalc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (rt_recalc && !IS_LSA_SELF(new)) {
|
|
|
|
/* RFC 2328 Section 13.2 Summary-LSAs
|
|
|
|
The best route to the destination described by the summary-
|
|
|
|
LSA must be recalculated (see Section 16.5). If this
|
|
|
|
destination is an AS boundary router, it may also be
|
|
|
|
necessary to re-examine all the AS-external-LSAs.
|
|
|
|
*/
|
2014-10-09 15:19:51 +02:00
|
|
|
ospf_spf_calculate_schedule(ospf,
|
|
|
|
SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* register LSA to refresh-list. */
|
|
|
|
if (IS_LSA_SELF(new))
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install AS-external-LSA. */
|
2003-03-25 06:07:42 +01:00
|
|
|
static struct ospf_lsa *ospf_external_lsa_install(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *new,
|
|
|
|
int rt_recalc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ase_register_external_lsa(new, ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If LSA is not self-originated, calculate an external route. */
|
|
|
|
if (rt_recalc) {
|
|
|
|
/* RFC 2328 Section 13.2 AS-external-LSAs
|
|
|
|
The best route to the destination described by the AS-
|
|
|
|
external-LSA must be recalculated (see Section 16.6).
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!IS_LSA_SELF(new))
|
2003-07-12 23:30:57 +02:00
|
|
|
ospf_ase_incremental_update(ospf, new);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
if (new->data->type == OSPF_AS_NSSA_LSA) {
|
|
|
|
/* There is no point to register selforiginate Type-7 LSA for
|
|
|
|
* refreshing. We rely on refreshing Type-5 LSA's
|
|
|
|
*/
|
|
|
|
if (IS_LSA_SELF(new))
|
|
|
|
return new;
|
|
|
|
else {
|
|
|
|
/* Try refresh type-5 translated LSA for this LSA, if
|
|
|
|
* one exists.
|
|
|
|
* New translations will be taken care of by the
|
|
|
|
* abr_task.
|
|
|
|
*/
|
|
|
|
ospf_translated_nssa_refresh(ospf, new, NULL);
|
2011-12-22 15:07:15 +01:00
|
|
|
ospf_schedule_abr_task(ospf);
|
2003-07-12 23:30:57 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-07-12 23:30:57 +02:00
|
|
|
/* Register self-originated LSA to refresh queue.
|
2003-07-13 03:36:06 +02:00
|
|
|
* Leave Translated LSAs alone if NSSA is enabled
|
2003-07-12 23:30:57 +02:00
|
|
|
*/
|
2004-06-20 23:00:27 +02:00
|
|
|
if (IS_LSA_SELF(new) && !CHECK_FLAG(new->flags, OSPF_LSA_LOCAL_XLT))
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_register_lsa(ospf, new);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_discard_from_db(struct ospf *ospf, struct ospf_lsdb *lsdb,
|
|
|
|
struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *old;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-08-20 20:05:53 +02:00
|
|
|
if (!lsdb)
|
2006-06-15 14:04:57 +02:00
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
old = ospf_lsdb_lookup(lsdb, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!old)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (old->refresh_list >= 0)
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_refresher_unregister_lsa(ospf, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (old->data->type) {
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
2005-05-11 20:09:59 +02:00
|
|
|
ospf_ase_unregister_external_lsa(old, ospf);
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ls_retransmit_delete_nbr_as(ospf, old);
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2005-05-11 20:09:59 +02:00
|
|
|
ospf_ls_retransmit_delete_nbr_as(ospf, old);
|
|
|
|
break;
|
2003-05-16 19:31:51 +02:00
|
|
|
case OSPF_AS_NSSA_LSA:
|
|
|
|
ospf_ls_retransmit_delete_nbr_area(old->area, old);
|
|
|
|
ospf_ase_unregister_external_lsa(old, ospf);
|
2004-06-20 23:00:27 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
default:
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ls_retransmit_delete_nbr_area(old->area, old);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_maxage_delete(ospf, old);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_discard(old);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
|
|
|
|
struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *new = NULL;
|
|
|
|
struct ospf_lsa *old = NULL;
|
|
|
|
struct ospf_lsdb *lsdb = NULL;
|
|
|
|
int rt_recalc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Set LSDB. */
|
|
|
|
switch (lsa->data->type) {
|
2002-12-13 22:44:27 +01:00
|
|
|
/* kevinm */
|
|
|
|
case OSPF_AS_NSSA_LSA:
|
|
|
|
if (lsa->area)
|
|
|
|
lsdb = lsa->area->lsdb;
|
|
|
|
else
|
2003-03-25 06:07:42 +01:00
|
|
|
lsdb = ospf->lsdb;
|
2002-12-13 22:44:27 +01:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
lsdb = ospf->lsdb;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
default:
|
2018-06-13 15:49:36 +02:00
|
|
|
if (lsa->area)
|
|
|
|
lsdb = lsa->area->lsdb;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(lsdb);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* RFC 2328 13.2. Installing LSAs in the database
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
Installing a new LSA in the database, either as the result of
|
|
|
|
flooding or a newly self-originated LSA, may cause the OSPF
|
|
|
|
routing table structure to be recalculated. The contents of the
|
|
|
|
new LSA should be compared to the old instance, if present. If
|
|
|
|
there is no difference, there is no need to recalculate the
|
|
|
|
routing table. When comparing an LSA to its previous instance,
|
|
|
|
the following are all considered to be differences in contents:
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
o The LSA's Options field has changed.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
o One of the LSA instances has LS age set to MaxAge, and
|
|
|
|
the other does not.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
o The length field in the LSA header has changed.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
o The body of the LSA (i.e., anything outside the 20-byte
|
|
|
|
LSA header) has changed. Note that this excludes changes
|
|
|
|
in LS Sequence Number and LS Checksum.
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
/* Look up old LSA and determine if any SPF calculation or incremental
|
|
|
|
update is needed */
|
|
|
|
old = ospf_lsdb_lookup(lsdb, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-04-19 14:18:43 +02:00
|
|
|
/* Do comparison and record if recalc needed. */
|
2002-12-13 21:15:29 +01:00
|
|
|
rt_recalc = 0;
|
2021-11-18 18:52:20 +01:00
|
|
|
if (old == NULL || ospf_lsa_different(old, lsa, false)) {
|
2020-08-22 19:49:30 +02:00
|
|
|
/* Ref rfc3623 section 3.2.3
|
|
|
|
* Installing new lsa or change in the existing LSA
|
|
|
|
* or flushing existing LSA leads to topo change
|
|
|
|
* and trigger SPF caculation.
|
|
|
|
* So, router should be aborted from HELPER role
|
|
|
|
* if it is detected as TOPO change.
|
|
|
|
*/
|
ospfd: crash when router acts as GR helper upon a topo change
Description:
ospf process is crashing when the current router acts
as GR helper and it received a new lsa.
Here, ospf_lsa_different() is being called without checking
'old' pointer. It is asserted in ospf_lsa_different() api
if the 'old' pointer is NULL.
corrected this by validaing old pointer before calling
ospf_lsa_different() api.
back tarce:
Program terminated with signal SIGABRT, Aborted.
0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
[Current thread is 1 (Thread 0x6b84348827c0 (LWP 3155))]
0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
1 0x00006b8433aa4801 in __GI_abort () at abort.c:79
2 0x00006b8433a9439a in __assert_fail_base (fmt=0x6b8433c1b7d8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x162ffc0630bc "l1", file=file@entry=0x162ffc062ff7 "ospfd/ospf_lsa.c", line=line@entry=3520, function=function@entry=0x162ffc0646f0 <__PRETTY_FUNCTION__.18732> "ospf_lsa_different") at assert.c:92
3 0x00006b8433a94412 in __GI___assert_fail (assertion=assertion@entry=0x162ffc0630bc "l1", file=file@entry=0x162ffc062ff7 "ospfd/ospf_lsa.c", line=line@entry=3520, function=function@entry=0x162ffc0646f0 <__PRETTY_FUNCTION__.18732> "ospf_lsa_different") at assert.c:101
4 0x0000162ffc008c25 in ospf_lsa_different (l1=l1@entry=0x0, l2=l2@entry=0x162ffe535c60, ignore_rcvd_flag=ignore_rcvd_flag@entry=true) at ospfd/ospf_lsa.c:3520
5 0x0000162ffc00a8e8 in ospf_lsa_install (ospf=ospf@entry=0x162ffe513650, oi=oi@entry=0x162ffe531c30, lsa=lsa@entry=0x162ffe535c60) at ospfd/ospf_lsa.c:2892
6 0x0000162ffc059d16 in ospf_flood (ospf=0x162ffe513650, nbr=nbr@entry=0x162ffe52cc90, current=current@entry=0x0, new=new@entry=0x162ffe535c60) at ospfd/ospf_flood.c:429
7 0x0000162ffc01838f in ospf_ls_upd (size=<optimized out>, oi=0x162ffe531c30, s=<optimized out>, ospfh=<optimized out>, iph=<optimized out>, ospf=<optimized out>) at ospfd/ospf_packet.c:2162
8 ospf_read_helper (ospf=<optimized out>) at ospfd/ospf_packet.c:3241
9 ospf_read (thread=<optimized out>) at ospfd/ospf_packet.c:3272
10 0x00006b843450139c in thread_call (thread=thread@entry=0x7780f42c7480) at lib/thread.c:1692
11 0x00006b84344cfb18 in frr_run (master=0x162ffe34d130) at lib/libfrr.c:1068
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-08-29 12:51:39 +02:00
|
|
|
if (ospf->active_restarter_cnt &&
|
|
|
|
CHECK_LSA_TYPE_1_TO_5_OR_7(lsa->data->type)) {
|
|
|
|
if (old == NULL || ospf_lsa_different(old, lsa, true))
|
|
|
|
ospf_helper_handle_topo_chg(ospf, lsa);
|
|
|
|
}
|
2020-08-22 19:49:30 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
rt_recalc = 1;
|
2020-08-22 19:49:30 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-10-13 11:06:46 +02:00
|
|
|
/*
|
|
|
|
Sequence number check (Section 14.1 of rfc 2328)
|
|
|
|
"Premature aging is used when it is time for a self-originated
|
|
|
|
LSA's sequence number field to wrap. At this point, the current
|
|
|
|
LSA instance (having LS sequence number MaxSequenceNumber) must
|
|
|
|
be prematurely aged and flushed from the routing domain before a
|
|
|
|
new instance with sequence number equal to InitialSequenceNumber
|
|
|
|
can be originated. "
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-03-30 16:16:11 +02:00
|
|
|
if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) {
|
2003-10-13 11:06:46 +02:00
|
|
|
if (ospf_lsa_is_self_originated(ospf, lsa)) {
|
2004-05-31 16:16:54 +02:00
|
|
|
lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-31 16:16:54 +02:00
|
|
|
if (!IS_LSA_MAXAGE(lsa))
|
2003-10-13 11:06:46 +02:00
|
|
|
lsa->flags |= OSPF_LSA_PREMATURE_AGE;
|
|
|
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-10-13 11:06:46 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH)) {
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"%s() Premature Aging lsa %p, seqnum 0x%x",
|
|
|
|
__func__, lsa,
|
2015-03-03 08:51:53 +01:00
|
|
|
ntohl(lsa->data->ls_seqnum));
|
2003-10-13 11:06:46 +02:00
|
|
|
ospf_lsa_header_dump(lsa->data);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"%s() got an lsa with seq 0x80000000 that was not self originated. Ignoring",
|
|
|
|
__func__);
|
2003-10-13 11:06:46 +02:00
|
|
|
ospf_lsa_header_dump(lsa->data);
|
|
|
|
}
|
|
|
|
return old;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2003-10-13 11:06:46 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* discard old LSA from LSDB */
|
|
|
|
if (old != NULL)
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_discard_from_db(ospf, lsdb, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Calculate Checksum if self-originated?. */
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_checksum(lsa->data);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-12-22 17:16:02 +01:00
|
|
|
/* Insert LSA to LSDB. */
|
|
|
|
ospf_lsdb_add(lsdb, lsa);
|
|
|
|
lsa->lsdb = lsdb;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Do LSA specific installation process. */
|
|
|
|
switch (lsa->data->type) {
|
|
|
|
case OSPF_ROUTER_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_router_lsa_install(ospf, lsa, rt_recalc);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_NETWORK_LSA:
|
|
|
|
assert(oi);
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_network_lsa_install(ospf, oi, lsa, rt_recalc);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_SUMMARY_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_summary_lsa_install(ospf, lsa, rt_recalc);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_ASBR_SUMMARY_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_summary_asbr_lsa_install(ospf, lsa, rt_recalc);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_external_lsa_install(ospf, lsa, rt_recalc);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
2003-01-18 01:12:02 +01:00
|
|
|
if (IS_LSA_SELF(lsa))
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa->oi = oi; /* Specify outgoing ospf-interface for
|
|
|
|
this LSA. */
|
2003-01-18 01:12:02 +01:00
|
|
|
else {
|
2012-12-04 22:43:42 +01:00
|
|
|
/* Incoming "oi" for this LSA has set at LSUpd
|
|
|
|
* reception. */
|
|
|
|
}
|
2003-01-18 01:12:02 +01:00
|
|
|
/* Fallthrough */
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
|
|
new = ospf_opaque_lsa_install(lsa, rt_recalc);
|
|
|
|
break;
|
2003-07-12 23:30:57 +02:00
|
|
|
case OSPF_AS_NSSA_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_external_lsa_install(ospf, lsa, rt_recalc);
|
2003-07-12 23:30:57 +02:00
|
|
|
default: /* type-6,8,9....nothing special */
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (new == NULL)
|
|
|
|
return new; /* Installation failed, cannot proceed further --
|
|
|
|
endo. */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Debug logs. */
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) {
|
|
|
|
switch (lsa->data->type) {
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2004-06-20 23:00:27 +02:00
|
|
|
case OSPF_AS_NSSA_LSA:
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[%s]: Install %s", dump_lsa_key(new),
|
2017-06-21 01:56:50 +02:00
|
|
|
lookup_msg(ospf_lsa_type_msg,
|
|
|
|
new->data->type, NULL));
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
default:
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[%s]: Install %s to Area %pI4",
|
2002-12-13 21:15:29 +01:00
|
|
|
dump_lsa_key(new),
|
2017-06-21 01:56:50 +02:00
|
|
|
lookup_msg(ospf_lsa_type_msg,
|
|
|
|
new->data->type, NULL),
|
2020-10-21 19:56:26 +02:00
|
|
|
&new->area->area_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-10-13 11:06:46 +02:00
|
|
|
/*
|
|
|
|
If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
|
|
|
|
(it's getting flushed out of the area), set LSA on MaxAge LSA list.
|
|
|
|
*/
|
2013-01-07 19:12:52 +01:00
|
|
|
if (IS_LSA_MAXAGE(new)) {
|
2003-10-13 11:06:46 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_INSTALL))
|
2021-05-31 15:27:51 +02:00
|
|
|
zlog_debug("LSA[%s]: Install LSA %p, MaxAge",
|
|
|
|
dump_lsa_key(new), lsa);
|
2013-01-07 19:12:52 +01:00
|
|
|
ospf_lsa_maxage(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
int ospf_check_nbr_status(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct ospf_interface *oi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_neighbor *nbr;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ospf_if_is_enable(oi))
|
|
|
|
for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
|
|
|
|
if ((nbr = rn->info) != NULL)
|
|
|
|
if (nbr->state == NSM_Exchange
|
|
|
|
|| nbr->state == NSM_Loading) {
|
|
|
|
route_unlock_node(rn);
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2022-08-26 09:58:37 +02:00
|
|
|
void ospf_maxage_lsa_remover(struct thread *thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf *ospf = THREAD_ARG(thread);
|
2020-12-23 14:20:22 +01:00
|
|
|
struct ospf_lsa *lsa, *old;
|
2012-12-04 19:46:37 +01:00
|
|
|
struct route_node *rn;
|
2002-12-13 21:15:29 +01:00
|
|
|
int reschedule = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->t_maxage = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[MaxAge]: remover Start");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
reschedule = !ospf_check_nbr_status(ospf);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!reschedule)
|
2012-12-04 19:46:37 +01:00
|
|
|
for (rn = route_top(ospf->maxage_lsa); rn;
|
|
|
|
rn = route_next(rn)) {
|
|
|
|
if ((lsa = rn->info) == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-02-20 11:00:52 +01:00
|
|
|
/* There is at least one neighbor from which we still
|
|
|
|
* await an ack
|
|
|
|
* for that LSA, so we are not allowed to remove it from
|
|
|
|
* our lsdb yet
|
|
|
|
* as per RFC 2328 section 14 para 4 a) */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (lsa->retransmit_counter > 0) {
|
|
|
|
reschedule = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-09 15:11:02 +01:00
|
|
|
/* TODO: maybe convert this function to a work-queue */
|
|
|
|
if (thread_should_yield(thread)) {
|
2013-02-20 11:00:52 +01:00
|
|
|
OSPF_TIMER_ON(ospf->t_maxage,
|
|
|
|
ospf_maxage_lsa_remover, 0);
|
2014-04-28 10:04:58 +02:00
|
|
|
route_unlock_node(
|
|
|
|
rn); /* route_top/route_next */
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2013-02-20 11:00:52 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Remove LSA from the LSDB */
|
2011-10-24 16:17:09 +02:00
|
|
|
if (IS_LSA_SELF(lsa))
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2011-12-02 17:02:40 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: LSA 0x%lx is self-originated: ",
|
2003-10-13 11:06:46 +02:00
|
|
|
lsa->data->type,
|
2020-10-21 19:56:26 +02:00
|
|
|
&lsa->data->id,
|
2018-03-27 21:13:34 +02:00
|
|
|
(unsigned long)lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"LSA[%s]: MaxAge LSA removed from list",
|
|
|
|
dump_lsa_key(lsa));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) {
|
2003-10-13 11:06:46 +02:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2015-03-03 08:51:53 +01:00
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"originating new lsa for lsa %p",
|
|
|
|
lsa);
|
2010-01-24 23:42:13 +01:00
|
|
|
ospf_lsa_refresh(ospf, lsa);
|
2003-10-13 11:06:46 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Remove from lsdb. */
|
2006-06-15 14:04:57 +02:00
|
|
|
if (lsa->lsdb) {
|
2020-12-23 14:20:22 +01:00
|
|
|
old = ospf_lsdb_lookup(lsa->lsdb, lsa);
|
|
|
|
/* The max age LSA here must be the same
|
|
|
|
* as the LSA in LSDB
|
|
|
|
*/
|
|
|
|
if (old != lsa) {
|
|
|
|
flog_err(EC_OSPF_LSA_MISSING,
|
2021-05-31 15:27:51 +02:00
|
|
|
"%s: LSA[%s]: LSA not in LSDB",
|
|
|
|
__func__, dump_lsa_key(lsa));
|
2021-01-27 21:00:10 +01:00
|
|
|
|
2020-12-23 14:20:22 +01:00
|
|
|
continue;
|
|
|
|
}
|
2006-06-15 14:04:57 +02:00
|
|
|
ospf_discard_from_db(ospf, lsa->lsdb, lsa);
|
|
|
|
ospf_lsdb_delete(lsa->lsdb, lsa);
|
2018-08-21 15:22:33 +02:00
|
|
|
} else {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"%s: LSA[%s]: No associated LSDB!",
|
|
|
|
__func__, dump_lsa_key(lsa));
|
2018-08-21 15:22:33 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* A MaxAge LSA must be removed immediately from the router's link
|
|
|
|
state database as soon as both a) it is no longer contained on any
|
|
|
|
neighbor Link state retransmission lists and b) none of the
|
|
|
|
router's
|
|
|
|
neighbors are in states Exchange or Loading. */
|
|
|
|
if (reschedule)
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover,
|
|
|
|
ospf->maxage_delay);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-09-03 14:10:26 +02:00
|
|
|
/* This function checks whether an LSA with initial sequence number should be
|
|
|
|
* originated after a wrap in sequence number
|
|
|
|
*/
|
|
|
|
void ospf_check_and_gen_init_seq_lsa(struct ospf_interface *oi,
|
|
|
|
struct ospf_lsa *recv_lsa)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa = NULL;
|
|
|
|
struct ospf *ospf = oi->ospf;
|
|
|
|
|
|
|
|
lsa = ospf_lsa_lookup_by_header(oi->area, recv_lsa->data);
|
|
|
|
|
|
|
|
if ((lsa == NULL) || (!CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE))
|
|
|
|
|| (lsa->retransmit_counter != 0)) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA))
|
|
|
|
zlog_debug(
|
|
|
|
"Do not generate LSA with initial seqence number.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ospf_lsa_maxage_delete(ospf, lsa);
|
|
|
|
|
|
|
|
lsa->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
|
|
|
|
|
|
|
ospf_lsa_refresh(ospf, lsa);
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_lsa_maxage_delete(struct ospf *ospf, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2012-12-04 19:46:37 +01:00
|
|
|
struct route_node *rn;
|
2017-10-02 23:07:13 +02:00
|
|
|
struct prefix lsa_prefix;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&lsa_prefix, 0, sizeof(lsa_prefix));
|
2022-02-07 19:20:43 +01:00
|
|
|
lsa_prefix.family = AF_UNSPEC;
|
2017-10-02 23:07:13 +02:00
|
|
|
lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
|
|
|
|
lsa_prefix.u.ptr = (uintptr_t)lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-04-08 07:57:15 +02:00
|
|
|
if ((rn = route_node_lookup(ospf->maxage_lsa, &lsa_prefix))) {
|
2012-12-04 19:46:37 +01:00
|
|
|
if (rn->info == lsa) {
|
|
|
|
UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
|
|
|
|
ospf_lsa_unlock(&lsa); /* maxage_lsa */
|
|
|
|
rn->info = NULL;
|
2014-04-28 10:04:59 +02:00
|
|
|
route_unlock_node(
|
|
|
|
rn); /* unlock node because lsa is deleted */
|
2012-12-04 19:46:37 +01:00
|
|
|
}
|
2014-04-28 10:04:59 +02:00
|
|
|
route_unlock_node(rn); /* route_node_lookup */
|
2017-10-02 23:07:13 +02:00
|
|
|
} else {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
zlog_debug("%s: lsa %s is not found in maxage db.",
|
2020-03-05 19:17:54 +01:00
|
|
|
__func__, dump_lsa_key(lsa));
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
/* Add LSA onto the MaxAge list, and schedule for removal.
|
|
|
|
* This does *not* lead to the LSA being flooded, that must be taken
|
|
|
|
* care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
|
|
|
|
* function).
|
|
|
|
*/
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-10-02 23:07:13 +02:00
|
|
|
struct prefix lsa_prefix;
|
2012-12-04 19:46:37 +01:00
|
|
|
struct route_node *rn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* When we saw a MaxAge LSA flooded to us, we put it on the list
|
|
|
|
and schedule the MaxAge LSA remover. */
|
2009-08-06 21:58:05 +02:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2021-05-31 15:27:51 +02:00
|
|
|
"LSA[%s]: %p already exists on MaxAge LSA list",
|
|
|
|
dump_lsa_key(lsa), lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&lsa_prefix, 0, sizeof(lsa_prefix));
|
2022-02-07 19:20:43 +01:00
|
|
|
lsa_prefix.family = AF_UNSPEC;
|
2017-10-02 23:07:13 +02:00
|
|
|
lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
|
|
|
|
lsa_prefix.u.ptr = (uintptr_t)lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-04-08 07:57:15 +02:00
|
|
|
rn = route_node_get(ospf->maxage_lsa, &lsa_prefix);
|
2018-06-14 14:58:05 +02:00
|
|
|
if (rn->info != NULL) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
|
|
|
zlog_debug(
|
|
|
|
"LSA[%s]: found LSA (%p) in table for LSA %p %d",
|
|
|
|
dump_lsa_key(lsa), rn->info,
|
|
|
|
(void *)lsa, lsa_prefix.prefixlen);
|
|
|
|
route_unlock_node(rn);
|
2012-12-04 19:46:37 +01:00
|
|
|
} else {
|
2018-06-14 14:58:05 +02:00
|
|
|
rn->info = ospf_lsa_lock(lsa);
|
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
|
2012-12-04 19:46:37 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[%s]: MaxAge LSA remover scheduled.",
|
|
|
|
dump_lsa_key(lsa));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
OSPF_TIMER_ON(ospf->t_maxage, ospf_maxage_lsa_remover,
|
|
|
|
ospf->maxage_delay);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
static int ospf_lsa_maxage_walker_remover(struct ospf *ospf,
|
|
|
|
struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* Stay away from any Local Translated Type-7 LSAs */
|
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_LSA_MAXAGE(lsa))
|
|
|
|
/* Self-originated LSAs should NOT time-out instead,
|
|
|
|
they're flushed and submitted to the max_age list explicitly.
|
|
|
|
*/
|
2003-03-25 06:07:42 +01:00
|
|
|
if (!ospf_lsa_is_self_originated(ospf, lsa)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[%s]: is MaxAge",
|
|
|
|
dump_lsa_key(lsa));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (lsa->data->type) {
|
2003-02-03 19:40:56 +01:00
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2003-01-18 01:12:02 +01:00
|
|
|
/*
|
|
|
|
* As a general rule, whenever network topology
|
|
|
|
* has changed
|
|
|
|
* (due to an LSA removal in this case), routing
|
|
|
|
* recalculation
|
|
|
|
* should be triggered. However, this is not
|
|
|
|
* true for opaque
|
|
|
|
* LSAs. Even if an opaque LSA instance is going
|
|
|
|
* to be removed
|
|
|
|
* from the routing domain, it does not mean a
|
|
|
|
* change in network
|
|
|
|
* topology, and thus, routing recalculation is
|
|
|
|
* not needed here.
|
|
|
|
*/
|
|
|
|
break;
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
2004-06-20 23:00:27 +02:00
|
|
|
case OSPF_AS_NSSA_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_ase_incremental_update(ospf, lsa);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
default:
|
2014-10-09 15:19:51 +02:00
|
|
|
ospf_spf_calculate_schedule(ospf,
|
|
|
|
SPF_FLAG_MAXAGE);
|
2003-03-25 06:07:42 +01:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf_lsa_maxage(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
if (IS_LSA_MAXAGE(lsa) && !ospf_lsa_is_self_originated(ospf, lsa))
|
|
|
|
if (LS_AGE(lsa) > OSPF_LSA_MAXAGE + 30)
|
|
|
|
printf("Eek! Shouldn't happen!\n");
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Periodical check of MaxAge LSA. */
|
2022-02-23 01:04:25 +01:00
|
|
|
void ospf_lsa_maxage_walker(struct thread *thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf *ospf = THREAD_ARG(thread);
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct listnode *node, *nnode;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->t_maxage_walker = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (ROUTER_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (NETWORK_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-05-10 22:06:51 +02:00
|
|
|
LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-05-10 22:06:51 +02:00
|
|
|
/* for AS-external-LSAs. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (ospf->lsdb) {
|
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_maxage_walker_remover(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
OSPF_TIMER_ON(ospf->t_maxage_walker, ospf_lsa_maxage_walker,
|
|
|
|
OSPF_LSA_MAXAGE_CHECK_INTERVAL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
struct ospf_lsa *ospf_lsa_lookup_by_prefix(struct ospf_lsdb *lsdb, uint8_t type,
|
2003-03-25 06:07:42 +01:00
|
|
|
struct prefix_ipv4 *p,
|
|
|
|
struct in_addr router_id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct in_addr mask, id;
|
|
|
|
struct lsa_header_mask {
|
|
|
|
struct lsa_header header;
|
|
|
|
struct in_addr mask;
|
|
|
|
} * hmask;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
lsa = ospf_lsdb_lookup_by_id(lsdb, type, p->prefix, router_id);
|
|
|
|
if (lsa == NULL)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
masklen2ip(p->prefixlen, &mask);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
hmask = (struct lsa_header_mask *)lsa->data;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
if (mask.s_addr != hmask->mask.s_addr) {
|
|
|
|
id.s_addr = p->prefix.s_addr | (~mask.s_addr);
|
|
|
|
lsa = ospf_lsdb_lookup_by_id(lsdb, type, id, router_id);
|
|
|
|
if (!lsa)
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
return lsa;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-25 22:51:12 +02:00
|
|
|
struct ospf_lsa *ospf_lsa_lookup(struct ospf *ospf, struct ospf_area *area,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t type, struct in_addr id,
|
2017-08-25 22:51:12 +02:00
|
|
|
struct in_addr adv_router)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-08-25 22:51:12 +02:00
|
|
|
if (!ospf)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (type) {
|
|
|
|
case OSPF_ROUTER_LSA:
|
|
|
|
case OSPF_NETWORK_LSA:
|
|
|
|
case OSPF_SUMMARY_LSA:
|
|
|
|
case OSPF_ASBR_SUMMARY_LSA:
|
|
|
|
case OSPF_AS_NSSA_LSA:
|
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
|
|
|
return ospf_lsdb_lookup_by_id(area->lsdb, type, id, adv_router);
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2003-04-13 22:20:53 +02:00
|
|
|
return ospf_lsdb_lookup_by_id(ospf->lsdb, type, id, adv_router);
|
2002-12-13 21:15:29 +01:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-03-27 21:13:34 +02:00
|
|
|
struct ospf_lsa *ospf_lsa_lookup_by_id(struct ospf_area *area, uint32_t type,
|
2002-12-13 21:15:29 +01:00
|
|
|
struct in_addr id)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
struct route_node *rn;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (type) {
|
|
|
|
case OSPF_ROUTER_LSA:
|
|
|
|
return ospf_lsdb_lookup_by_id(area->lsdb, type, id, id);
|
|
|
|
case OSPF_NETWORK_LSA:
|
|
|
|
for (rn = route_top(NETWORK_LSDB(area)); rn;
|
|
|
|
rn = route_next(rn))
|
|
|
|
if ((lsa = rn->info))
|
|
|
|
if (IPV4_ADDR_SAME(&lsa->data->id, &id)) {
|
|
|
|
route_unlock_node(rn);
|
|
|
|
return lsa;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OSPF_SUMMARY_LSA:
|
|
|
|
case OSPF_ASBR_SUMMARY_LSA:
|
|
|
|
/* Currently not used. */
|
|
|
|
assert(1);
|
|
|
|
return ospf_lsdb_lookup_by_id(area->lsdb, type, id, id);
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
2003-07-12 23:30:57 +02:00
|
|
|
case OSPF_AS_NSSA_LSA:
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
|
|
/* Currently not used. */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area,
|
|
|
|
struct lsa_header *lsah)
|
|
|
|
{
|
|
|
|
struct ospf_lsa *match;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
|
|
|
|
* is redefined to have two subfields; opaque-type and opaque-id.
|
|
|
|
* However, it is harmless to treat the two sub fields together, as if
|
|
|
|
* they two were forming a unique LSA-ID.
|
|
|
|
*/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-25 22:51:12 +02:00
|
|
|
match = ospf_lsa_lookup(area->ospf, area, lsah->type, lsah->id,
|
|
|
|
lsah->adv_router);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (match == NULL)
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
|
2020-10-21 19:56:26 +02:00
|
|
|
zlog_debug("LSA[Type%d:%pI4]: Lookup by header, NO MATCH",
|
|
|
|
lsah->type, &lsah->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return +n, l1 is more recent.
|
|
|
|
return -n, l2 is more recent.
|
|
|
|
return 0, l1 and l2 is identical. */
|
|
|
|
int ospf_lsa_more_recent(struct ospf_lsa *l1, struct ospf_lsa *l2)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
int x, y;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (l1 == NULL && l2 == NULL)
|
|
|
|
return 0;
|
|
|
|
if (l1 == NULL)
|
|
|
|
return -1;
|
|
|
|
if (l2 == NULL)
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* compare LS sequence number. */
|
|
|
|
x = (int)ntohl(l1->data->ls_seqnum);
|
|
|
|
y = (int)ntohl(l2->data->ls_seqnum);
|
|
|
|
if (x > y)
|
|
|
|
return 1;
|
|
|
|
if (x < y)
|
|
|
|
return -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* compare LS checksum. */
|
|
|
|
r = ntohs(l1->data->checksum) - ntohs(l2->data->checksum);
|
|
|
|
if (r)
|
|
|
|
return r;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* compare LS age. */
|
|
|
|
if (IS_LSA_MAXAGE(l1) && !IS_LSA_MAXAGE(l2))
|
|
|
|
return 1;
|
|
|
|
else if (!IS_LSA_MAXAGE(l1) && IS_LSA_MAXAGE(l2))
|
|
|
|
return -1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* compare LS age with MaxAgeDiff. */
|
|
|
|
if (LS_AGE(l1) - LS_AGE(l2) > OSPF_LSA_MAXAGE_DIFF)
|
|
|
|
return -1;
|
|
|
|
else if (LS_AGE(l2) - LS_AGE(l1) > OSPF_LSA_MAXAGE_DIFF)
|
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSAs are identical. */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-11-18 18:52:20 +01:00
|
|
|
/*
|
|
|
|
* Check if two LSAs are different.
|
|
|
|
*
|
|
|
|
* l1
|
|
|
|
* The first LSA to compare.
|
|
|
|
*
|
|
|
|
* l2
|
|
|
|
* The second LSA to compare.
|
|
|
|
*
|
|
|
|
* ignore_rcvd_flag
|
|
|
|
* When set to true, ignore whether the LSAs were received from the network
|
|
|
|
* or not. This parameter should be set to true when checking for topology
|
|
|
|
* changes as part of the Graceful Restart helper neighbor procedures.
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* true if the LSAs are different, false otherwise.
|
|
|
|
*/
|
|
|
|
int ospf_lsa_different(struct ospf_lsa *l1, struct ospf_lsa *l2,
|
|
|
|
bool ignore_rcvd_flag)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
char *p1, *p2;
|
|
|
|
assert(l1);
|
|
|
|
assert(l2);
|
|
|
|
assert(l1->data);
|
|
|
|
assert(l2->data);
|
|
|
|
|
|
|
|
if (l1->data->options != l2->data->options)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (IS_LSA_MAXAGE(l1) && !IS_LSA_MAXAGE(l2))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if (IS_LSA_MAXAGE(l2) && !IS_LSA_MAXAGE(l1))
|
|
|
|
return 1;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
if (l1->size != l2->size)
|
2002-12-13 21:15:29 +01:00
|
|
|
return 1;
|
|
|
|
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
if (l1->size == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
return 1;
|
|
|
|
|
2021-11-18 18:52:20 +01:00
|
|
|
if (!ignore_rcvd_flag
|
|
|
|
&& CHECK_FLAG((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
|
2009-07-27 12:42:35 +02:00
|
|
|
return 1; /* May be a stale LSA in the LSBD */
|
|
|
|
|
2022-10-27 21:12:23 +02:00
|
|
|
if (l1->size == OSPF_LSA_HEADER_SIZE)
|
|
|
|
return 0; /* nothing to compare */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
p1 = (char *)l1->data;
|
|
|
|
p2 = (char *)l2->data;
|
|
|
|
|
|
|
|
if (memcmp(p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
|
ospfd: Correct Coverity defects
When browsing or parsing OSPF LSA TLVs, we need to use the LSA length which is
part of the LSA header. This length, encoded in 16 bits, must be first
converted to host byte order with ntohs() function. However, Coverity Scan
considers that ntohs() function return TAINTED data. Thus, when the length is
used to control for() loop, Coverity Scan marks this part of the code as defect
with "Untrusted Loop Bound" due to the usage of Tainted variable. Similar
problems occur when browsing sub-TLV where length is extracted with ntohs().
To overcome this limitation, a size attribute has been added to the ospf_lsa
structure. The size is set when lsa->data buffer is allocated. In addition,
when an OSPF packet is received, the size of the payload is controlled before
contains is processed. For OSPF LSA, this allow a secure buffer allocation.
Thus, new size attribute contains the exact buffer allocation allowing a
strict control during TLV browsing.
This patch adds extra control to bound for() loop during TLV browsing to
avoid potential problem as suggested by Coverity Scan. Controls are based
on new size attribute of the ospf_lsa structure to avoid any ambiguity.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
2021-04-06 12:09:25 +02:00
|
|
|
l1->size - OSPF_LSA_HEADER_SIZE)
|
2002-12-13 21:15:29 +01:00
|
|
|
!= 0)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
int ospf_lsa_flush_schedule(struct ospf *ospf, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (lsa == NULL || !IS_LSA_SELF(lsa))
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
|
|
|
|
lsa->data->type, &lsa->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Force given lsa's age to MaxAge. */
|
|
|
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (lsa->data->type) {
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
/* Opaque wants to be notified of flushes */
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
|
|
|
ospf_opaque_lsa_refresh(lsa);
|
|
|
|
break;
|
|
|
|
default:
|
2010-04-14 11:32:12 +02:00
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
ospfd: Fix maxage/flush to not try flood twice, remember maxages for longer
2006-05-30 Paul Jakma <paul.jakma@sun.com>
* (general) Fix confusion around MaxAge-ing and problem with
high-latency networks. Analysis and suggested fixes by
Phillip Spagnolo, in [quagga-dev 4132], on which this commit
expands slightly.
* ospf_flood.{c,h}: (ospf_lsa_flush) new function.
Scope-general form of existing flush functions, essentially
the dormant ospf_maxage_flood() but without the ambiguity of
whether it is responsible for flooding.
* ospf_lsa.c: (ospf_lsa_maxage) Role minimised to simply setup
LSA on the Maxage list and schedule removal - no more.
ospf_lsa_flush* being the primary way to kick-off flushes
of LSAs.
Don't hardcode the remover-timer value, which was too
short for very high-latency networks.
(ospf_maxage_lsa_remover) Just do what needs to be done to
remove maxage LSAs from the maxage list, remove the call
to ospf_flood_through().
Don't hardcode remove-timer value.
(ospf_lsa_{install,flush_schedule}) ospf_lsa_flush is the correct
entrypoint to flushing maxaged LSAs.
(lsa_header_set) Use a define for the initial age, useful for
testing.
* ospf_opaque.c: (ospf_opaque_lsa_refresh) ditto.
(ospf_opaque_lsa_flush_schedule) ditto.
* ospfd.h: ({struct ospf,ospf_new}) Add maxage_delay parameter,
interval to wait before running the maxage_remover. Supply a
suitable default.
Add a define for OSPF_LSA_INITIAL_AGE, see lsa_header_set().
2010-01-25 00:36:20 +01:00
|
|
|
ospf_lsa_flush(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_flush_self_originated_lsas_now(struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
|
|
|
struct listnode *node2, *nnode2;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_interface *oi;
|
|
|
|
struct ospf_lsa *lsa;
|
2003-03-25 06:07:42 +01:00
|
|
|
struct route_node *rn;
|
2022-11-15 06:00:55 +01:00
|
|
|
struct ospf_if_params *oip;
|
2002-12-13 21:15:29 +01:00
|
|
|
int need_to_flush_ase = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-11-07 03:17:19 +01:00
|
|
|
ospf->inst_shutdown = 1;
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(ospf->areas, node, nnode, area)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((lsa = area->router_lsa_self) != NULL) {
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2010-04-14 11:32:12 +02:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
|
2010-04-14 11:32:12 +02:00
|
|
|
lsa->data->type,
|
2020-10-21 19:56:26 +02:00
|
|
|
&lsa->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-14 11:32:12 +02:00
|
|
|
ospf_refresher_unregister_lsa(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_flush_area(lsa, area);
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&area->router_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
area->router_lsa_self = NULL;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(area->oiflist, node2, nnode2, oi)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((lsa = oi->network_lsa_self) != NULL
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
&& oi->state == ISM_DR && oi->full_nbrs > 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2010-04-14 11:32:12 +02:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
|
2010-04-14 11:32:12 +02:00
|
|
|
lsa->data->type,
|
2020-10-21 19:56:26 +02:00
|
|
|
&lsa->data->id);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-14 11:32:12 +02:00
|
|
|
ospf_refresher_unregister_lsa(
|
|
|
|
ospf, oi->network_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
ospf_lsa_flush_area(oi->network_lsa_self, area);
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&oi->network_lsa_self);
|
2002-12-13 21:15:29 +01:00
|
|
|
oi->network_lsa_self = NULL;
|
2022-11-15 06:00:55 +01:00
|
|
|
|
|
|
|
oip = ospf_lookup_if_params(
|
|
|
|
oi->ifp, oi->address->u.prefix4);
|
|
|
|
if (oip)
|
|
|
|
oip->network_lsa_seqnum = htonl(
|
|
|
|
OSPF_INVALID_SEQUENCE_NUMBER);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (oi->type != OSPF_IFTYPE_VIRTUALLINK
|
|
|
|
&& area->external_routing == OSPF_AREA_DEFAULT)
|
|
|
|
need_to_flush_ase = 1;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (need_to_flush_ase) {
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
2018-01-17 19:28:17 +01:00
|
|
|
ospf_lsa_flush_schedule(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Make sure that the MaxAge LSA remover is executed immediately,
|
|
|
|
* without conflicting to other threads.
|
|
|
|
*/
|
2003-03-25 06:07:42 +01:00
|
|
|
if (ospf->t_maxage != NULL) {
|
2022-06-03 16:28:11 +02:00
|
|
|
THREAD_OFF(ospf->t_maxage);
|
2003-03-25 06:07:42 +01:00
|
|
|
thread_execute(master, ospf_maxage_lsa_remover, ospf, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-11-21 13:50:16 +01:00
|
|
|
/** @brief Function to refresh all the self originated
|
|
|
|
* LSAs for area, when FR state change happens.
|
|
|
|
* @param area pointer.
|
|
|
|
* @return Void.
|
|
|
|
*/
|
|
|
|
void ospf_refresh_area_self_lsas(struct ospf_area *area)
|
|
|
|
{
|
|
|
|
struct listnode *node2;
|
|
|
|
struct listnode *nnode2;
|
|
|
|
struct ospf_interface *oi;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
|
|
|
|
if (!area)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (area->router_lsa_self)
|
|
|
|
ospf_lsa_refresh(area->ospf, area->router_lsa_self);
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS(area->oiflist, node2, nnode2, oi))
|
|
|
|
if (oi->network_lsa_self)
|
|
|
|
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
|
|
|
|
|
|
|
|
LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
LSDB_LOOP (ASBR_SUMMARY_LSDB(area), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
LSDB_LOOP (OPAQUE_LINK_LSDB(area), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
LSDB_LOOP (OPAQUE_AREA_LSDB(area), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(area->ospf), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
LSDB_LOOP (OPAQUE_AS_LSDB(area->ospf), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_refresh(area->ospf, lsa);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If there is self-originated LSA, then return 1, otherwise return 0. */
|
|
|
|
/* An interface-independent version of ospf_lsa_is_self_originated */
|
2003-03-25 06:07:42 +01:00
|
|
|
int ospf_lsa_is_self_originated(struct ospf *ospf, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct listnode *node;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct ospf_interface *oi;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* This LSA is already checked. */
|
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_SELF_CHECKED))
|
2011-10-24 16:17:09 +02:00
|
|
|
return IS_LSA_SELF(lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Make sure LSA is self-checked. */
|
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_SELF_CHECKED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* AdvRouter and Router ID is the same. */
|
2003-03-25 06:07:42 +01:00
|
|
|
if (IPV4_ADDR_SAME(&lsa->data->adv_router, &ospf->router_id))
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_SELF);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSA is router-LSA. */
|
|
|
|
else if (lsa->data->type == OSPF_ROUTER_LSA
|
2003-03-25 06:07:42 +01:00
|
|
|
&& IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id))
|
2002-12-13 21:15:29 +01:00
|
|
|
SET_FLAG(lsa->flags, OSPF_LSA_SELF);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSA is network-LSA. Compare Link ID with all interfaces. */
|
|
|
|
else if (lsa->data->type == OSPF_NETWORK_LSA)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Ignore virtual link. */
|
|
|
|
if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
|
|
|
|
if (oi->address->family == AF_INET)
|
|
|
|
if (IPV4_ADDR_SAME(
|
|
|
|
&lsa->data->id,
|
|
|
|
&oi->address->u.prefix4)) {
|
|
|
|
/* to make it easier later */
|
|
|
|
SET_FLAG(lsa->flags,
|
|
|
|
OSPF_LSA_SELF);
|
2011-10-24 16:17:09 +02:00
|
|
|
return IS_LSA_SELF(lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2011-10-24 16:17:09 +02:00
|
|
|
return IS_LSA_SELF(lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get unique Link State ID. */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
enum lsid_status ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb,
|
|
|
|
uint8_t type, struct prefix_ipv4 *p,
|
|
|
|
struct in_addr *id)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ospf_lsa *lsa;
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
struct in_addr mask;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
*id = p->prefix;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check existence of LSA instance. */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
lsa = ospf_lsdb_lookup_by_id(lsdb, type, *id, ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (lsa) {
|
|
|
|
struct as_external_lsa *al =
|
|
|
|
(struct as_external_lsa *)lsa->data;
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
/* Ref rfc2328,Appendex E.1
|
|
|
|
* If router already originated the external lsa with lsid
|
|
|
|
* as the current prefix, and the masklens are same then
|
|
|
|
* terminate the LSID algorithem.
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ip_masklen(al->mask) == p->prefixlen) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
"%s: Can't get Link State ID for %pFX",
|
|
|
|
__func__, p);
|
2002-12-13 21:15:29 +01:00
|
|
|
/* id.s_addr = 0; */
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
id->s_addr = 0xffffffff;
|
|
|
|
return LSID_NOT_AVAILABLE;
|
|
|
|
} else if (ip_masklen(al->mask) < p->prefixlen) {
|
|
|
|
/* Ref rfc2328,Appendex E.2
|
|
|
|
* the current prefix masklen is greater than the
|
|
|
|
* existing LSA, then generate the Link state ID,
|
|
|
|
* by setting all host bits in prefix addressa and
|
|
|
|
* originate.
|
|
|
|
*
|
|
|
|
* Eg: 1st Route : 10.0.0.0/16 - LSID:10.0.0.0
|
|
|
|
* 2nd Route : 10.0.0.0/24 - LSID:10.0.0.255
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
masklen2ip(p->prefixlen, &mask);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
id->s_addr = p->prefix.s_addr | (~mask.s_addr);
|
|
|
|
lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, type, *id,
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->router_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (lsa) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug(
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
"%s: Can't get Link State ID for %pFX",
|
|
|
|
__func__, p);
|
|
|
|
id->s_addr = 0xffffffff;
|
|
|
|
return LSID_NOT_AVAILABLE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Ref rfc2328,Appendex E.3
|
|
|
|
* the current prefix masklen is lesser than the
|
|
|
|
* existing LSA,then the originated LSA has to be
|
|
|
|
* refreshed by modifying masklen, cost and tag.
|
|
|
|
* Originate the old route info with new LSID by
|
|
|
|
* setting the host bits in prefix address.
|
|
|
|
*
|
|
|
|
* Eg: 1st Route : 10.0.0.0/24 - LSID:10.0.0.0
|
|
|
|
* 2nd Route : 10.0.0.0/16 - ?
|
|
|
|
* Since 2nd route mask len is less than firstone
|
|
|
|
* LSID has to be changed.
|
|
|
|
* 1st route LSID:10.0.0.255
|
|
|
|
* 2nd route LSID:10.0.0.0
|
|
|
|
*/
|
|
|
|
id->s_addr = lsa->data->id.s_addr | (~al->mask.s_addr);
|
|
|
|
lsa = ospf_lsdb_lookup_by_id(ospf->lsdb, type, *id,
|
|
|
|
ospf->router_id);
|
|
|
|
if (lsa && (ip_masklen(al->mask) != IPV4_MAX_BITLEN)) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
|
|
|
zlog_debug(
|
|
|
|
"%s: Can't get Link State ID for %pFX",
|
|
|
|
__func__, p);
|
|
|
|
id->s_addr = 0xffffffff;
|
|
|
|
return LSID_NOT_AVAILABLE;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
return LSID_CHANGE;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
ospfd: Modifying LSID generation algorithm
Description:
This LSID alogithm added as per rcf2328 Appendex-E recommendation.
This applies only for AS-external lsas and summary lsas.
As an example of the algorithm, consider its operation when the
following sequence of events occurs in a single router (Router A).
(1) Router A wants to originate an AS-external-LSA for
[10.0.0.0,255.255.255.0]:
(a) A Link State ID of 10.0.0.0 is used.
(2) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.255.0.0]:
(a) The LSA for [10.0.0,0,255.255.255.0] is reoriginated using a
new Link State ID of 10.0.0.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.255.0.0].
(3) Router A then wants to originate an AS-external-LSA for
[10.0.0.0,255.0.0.0]:
(a) The LSA for [10.0.0.0,255.255.0.0] is reoriginated using a
new Link State ID of 10.0.255.255.
(b) A Link State ID of 10.0.0.0 is used for
[10.0.0.0,255.0.0.0].
(c) The network [10.0.0.0,255.255.255.0] keeps its Link State ID
of 10.0.0.255.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
2022-01-05 18:45:33 +01:00
|
|
|
return LSID_AVAILABLE;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2006-05-13 00:57:57 +02:00
|
|
|
#define LSA_ACTION_FLOOD_AREA 1
|
|
|
|
#define LSA_ACTION_FLUSH_AREA 2
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
struct lsa_action {
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t action;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ospf_area *area;
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
};
|
|
|
|
|
2022-02-23 01:04:25 +01:00
|
|
|
static void ospf_lsa_action(struct thread *t)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct lsa_action *data;
|
|
|
|
|
|
|
|
data = THREAD_ARG(t);
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
|
2004-12-08 19:12:06 +01:00
|
|
|
zlog_debug("LSA[Action]: Performing scheduled LSA action: %d",
|
2002-12-13 21:15:29 +01:00
|
|
|
data->action);
|
|
|
|
|
|
|
|
switch (data->action) {
|
|
|
|
case LSA_ACTION_FLOOD_AREA:
|
|
|
|
ospf_flood_through_area(data->area, NULL, data->lsa);
|
|
|
|
break;
|
|
|
|
case LSA_ACTION_FLUSH_AREA:
|
|
|
|
ospf_lsa_flush_area(data->lsa, data->area);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-07-26 11:37:26 +02:00
|
|
|
ospf_lsa_unlock(&data->lsa); /* Message */
|
2002-12-13 21:15:29 +01:00
|
|
|
XFREE(MTYPE_OSPF_MESSAGE, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ospf_schedule_lsa_flood_area(struct ospf_area *area, struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
struct lsa_action *data;
|
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
data = XCALLOC(MTYPE_OSPF_MESSAGE, sizeof(struct lsa_action));
|
2002-12-13 21:15:29 +01:00
|
|
|
data->action = LSA_ACTION_FLOOD_AREA;
|
|
|
|
data->area = area;
|
2006-07-26 11:37:26 +02:00
|
|
|
data->lsa = ospf_lsa_lock(lsa); /* Message / Flood area */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-04-25 00:33:25 +02:00
|
|
|
thread_add_event(master, ospf_lsa_action, data, 0, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa)
|
|
|
|
{
|
|
|
|
struct lsa_action *data;
|
|
|
|
|
2008-08-18 23:13:29 +02:00
|
|
|
data = XCALLOC(MTYPE_OSPF_MESSAGE, sizeof(struct lsa_action));
|
2002-12-13 21:15:29 +01:00
|
|
|
data->action = LSA_ACTION_FLUSH_AREA;
|
|
|
|
data->area = area;
|
2006-07-26 11:37:26 +02:00
|
|
|
data->lsa = ospf_lsa_lock(lsa); /* Message / Flush area */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-04-25 00:33:25 +02:00
|
|
|
thread_add_event(master, ospf_lsa_action, data, 0, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* LSA Refreshment functions. */
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct external_info *ei;
|
2020-09-05 17:15:51 +02:00
|
|
|
struct ospf_external_aggr_rt *aggr;
|
2010-01-24 23:42:13 +01:00
|
|
|
struct ospf_lsa *new = NULL;
|
2020-09-05 17:15:51 +02:00
|
|
|
struct as_external_lsa *al;
|
|
|
|
struct prefix_ipv4 p;
|
|
|
|
|
2023-01-17 17:11:56 +01:00
|
|
|
assert(CHECK_FLAG(lsa->flags, OSPF_LSA_SELF));
|
|
|
|
assert(IS_LSA_SELF(lsa));
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(lsa->lock > 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-01-24 23:42:13 +01:00
|
|
|
switch (lsa->data->type) {
|
|
|
|
/* Router and Network LSAs are processed differently. */
|
2002-12-13 21:15:29 +01:00
|
|
|
case OSPF_ROUTER_LSA:
|
2010-01-24 23:42:13 +01:00
|
|
|
new = ospf_router_lsa_refresh(lsa);
|
|
|
|
break;
|
2003-03-25 06:07:42 +01:00
|
|
|
case OSPF_NETWORK_LSA:
|
2016-05-18 15:36:38 +02:00
|
|
|
new = ospf_network_lsa_refresh(lsa);
|
|
|
|
break;
|
|
|
|
case OSPF_SUMMARY_LSA:
|
2017-01-18 01:30:43 +01:00
|
|
|
new = ospf_summary_lsa_refresh(ospf, lsa);
|
2003-03-25 06:07:42 +01:00
|
|
|
break;
|
2015-03-03 08:51:53 +01:00
|
|
|
case OSPF_ASBR_SUMMARY_LSA:
|
2003-03-25 06:07:42 +01:00
|
|
|
new = ospf_summary_asbr_lsa_refresh(ospf, lsa);
|
|
|
|
break;
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Translated from NSSA Type-5s are refreshed when
|
2004-09-23 21:18:23 +02:00
|
|
|
* from refresh of Type-7 - do not refresh these directly.
|
2006-07-26 11:37:26 +02:00
|
|
|
*/
|
2020-09-05 17:15:51 +02:00
|
|
|
|
|
|
|
al = (struct as_external_lsa *)lsa->data;
|
|
|
|
p.family = AF_INET;
|
|
|
|
p.prefixlen = ip_masklen(al->mask);
|
|
|
|
p.prefix = lsa->data->id;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
|
2016-05-18 15:36:38 +02:00
|
|
|
break;
|
2017-08-25 22:51:12 +02:00
|
|
|
ei = ospf_external_info_check(ospf, lsa);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ei)
|
2020-08-15 11:55:40 +02:00
|
|
|
new = ospf_external_lsa_refresh(
|
|
|
|
ospf, lsa, ei, LSA_REFRESH_FORCE, false);
|
2020-09-05 17:15:51 +02:00
|
|
|
else {
|
|
|
|
aggr = (struct ospf_external_aggr_rt *)
|
|
|
|
ospf_extrenal_aggregator_lookup(ospf, &p);
|
|
|
|
if (aggr) {
|
|
|
|
struct external_info ei_aggr;
|
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&ei_aggr, 0, sizeof(ei_aggr));
|
2020-09-05 17:15:51 +02:00
|
|
|
ei_aggr.p = aggr->p;
|
|
|
|
ei_aggr.tag = aggr->tag;
|
|
|
|
ei_aggr.instance = ospf->instance;
|
|
|
|
ei_aggr.route_map_set.metric = -1;
|
|
|
|
ei_aggr.route_map_set.metric_type = -1;
|
|
|
|
|
|
|
|
ospf_external_lsa_refresh(ospf, lsa, &ei_aggr,
|
|
|
|
LSA_REFRESH_FORCE, true);
|
2021-08-16 13:27:45 +02:00
|
|
|
SET_FLAG(aggr->flags,
|
|
|
|
OSPF_EXTERNAL_AGGRT_ORIGINATED);
|
2020-09-05 17:15:51 +02:00
|
|
|
} else
|
|
|
|
ospf_lsa_flush_as(ospf, lsa);
|
|
|
|
}
|
2003-03-25 06:07:42 +01:00
|
|
|
break;
|
|
|
|
case OSPF_OPAQUE_LINK_LSA:
|
2016-05-18 15:36:38 +02:00
|
|
|
case OSPF_OPAQUE_AREA_LSA:
|
2010-04-13 23:33:54 +02:00
|
|
|
case OSPF_OPAQUE_AS_LSA:
|
2017-05-05 23:22:25 +02:00
|
|
|
new = ospf_opaque_lsa_refresh(lsa);
|
|
|
|
break;
|
2017-01-18 01:30:43 +01:00
|
|
|
default:
|
2010-04-13 23:33:54 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint16_t index, current_index;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-13 23:33:54 +02:00
|
|
|
assert(lsa->lock > 0);
|
2023-01-17 17:11:56 +01:00
|
|
|
assert(IS_LSA_SELF(lsa));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (lsa->refresh_list < 0) {
|
|
|
|
int delay;
|
2016-05-18 15:36:38 +02:00
|
|
|
int min_delay =
|
2022-08-26 09:58:37 +02:00
|
|
|
ospf->lsa_refresh_timer - (2 * OSPF_LS_REFRESH_JITTER);
|
|
|
|
int max_delay =
|
|
|
|
ospf->lsa_refresh_timer - OSPF_LS_REFRESH_JITTER;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-05-18 15:36:38 +02:00
|
|
|
/* We want to refresh the LSA within OSPF_LS_REFRESH_TIME which
|
2017-07-17 14:03:14 +02:00
|
|
|
* is
|
2016-05-18 15:36:38 +02:00
|
|
|
* 1800s. Use jitter so that we send the LSA sometime between
|
2017-07-17 14:03:14 +02:00
|
|
|
* 1680s
|
2016-05-18 15:36:38 +02:00
|
|
|
* and 1740s.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2020-04-17 15:35:15 +02:00
|
|
|
delay = (frr_weak_random() % (max_delay - min_delay))
|
|
|
|
+ min_delay;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
current_index = ospf->lsa_refresh_queue.index
|
|
|
|
+ (monotime(NULL) - ospf->lsa_refresher_started)
|
2010-01-24 23:42:13 +01:00
|
|
|
/ OSPF_LSA_REFRESHER_GRANULARITY;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
index = (current_index + delay / OSPF_LSA_REFRESHER_GRANULARITY)
|
2010-01-24 23:42:13 +01:00
|
|
|
% (OSPF_LSA_REFRESHER_SLOTS);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2016-05-18 15:36:38 +02:00
|
|
|
zlog_debug(
|
2020-10-21 19:56:26 +02:00
|
|
|
"LSA[Refresh:Type%d:%pI4]: age %d, added to index %d",
|
|
|
|
lsa->data->type, &lsa->data->id,
|
2016-05-18 15:36:38 +02:00
|
|
|
LS_AGE(lsa), index);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
if (!ospf->lsa_refresh_queue.qs[index])
|
|
|
|
ospf->lsa_refresh_queue.qs[index] = list_new();
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-07-26 11:37:26 +02:00
|
|
|
listnode_add(ospf->lsa_refresh_queue.qs[index],
|
|
|
|
ospf_lsa_lock(lsa)); /* lsa_refresh_queue */
|
2002-12-13 21:15:29 +01:00
|
|
|
lsa->refresh_list = index;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2016-05-18 15:36:38 +02:00
|
|
|
zlog_debug(
|
2022-08-24 19:56:16 +02:00
|
|
|
"LSA[Refresh:Type%d:%pI4]: %s: setting refresh_list on lsa %p (slot %d)",
|
|
|
|
lsa->data->type, &lsa->data->id, __func__,
|
|
|
|
(void *)lsa, index);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2010-04-13 23:33:54 +02:00
|
|
|
assert(lsa->lock > 0);
|
2023-01-17 17:11:56 +01:00
|
|
|
assert(IS_LSA_SELF(lsa));
|
2002-12-13 21:15:29 +01:00
|
|
|
if (lsa->refresh_list >= 0) {
|
2004-09-23 21:18:23 +02:00
|
|
|
struct list *refresh_list =
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->lsa_refresh_queue.qs[lsa->refresh_list];
|
2002-12-13 21:15:29 +01:00
|
|
|
listnode_delete(refresh_list, lsa);
|
|
|
|
if (!listcount(refresh_list)) {
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&refresh_list);
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
lsa->refresh_list = -1;
|
2019-03-29 12:25:45 +01:00
|
|
|
ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 01:04:25 +01:00
|
|
|
void ospf_lsa_refresh_walker(struct thread *t)
|
2017-07-17 14:03:14 +02:00
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
struct list *refresh_list;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct listnode *node, *nnode;
|
2003-03-25 06:07:42 +01:00
|
|
|
struct ospf *ospf = THREAD_ARG(t);
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
struct ospf_lsa *lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
int i;
|
2004-09-23 21:18:23 +02:00
|
|
|
struct list *lsa_to_refresh = list_new();
|
2022-11-21 13:50:16 +01:00
|
|
|
bool dna_lsa;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("LSA[Refresh]: %s: start", __func__);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
i = ospf->lsa_refresh_queue.index;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-03-13 20:27:22 +01:00
|
|
|
/* Note: if clock has jumped backwards, then time change could be
|
|
|
|
negative,
|
|
|
|
so we are careful to cast the expression to unsigned before taking
|
|
|
|
modulus. */
|
2017-01-18 01:30:43 +01:00
|
|
|
ospf->lsa_refresh_queue.index =
|
2005-03-13 20:27:22 +01:00
|
|
|
((unsigned long)(ospf->lsa_refresh_queue.index
|
2017-01-18 01:30:43 +01:00
|
|
|
+ (monotime(NULL)
|
|
|
|
- ospf->lsa_refresher_started)
|
2010-01-24 23:42:13 +01:00
|
|
|
/ OSPF_LSA_REFRESHER_GRANULARITY))
|
|
|
|
% OSPF_LSA_REFRESHER_SLOTS;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("LSA[Refresh]: %s: next index %d", __func__,
|
|
|
|
ospf->lsa_refresh_queue.index);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-01-18 01:30:43 +01:00
|
|
|
for (; i != ospf->lsa_refresh_queue.index;
|
2002-12-13 21:15:29 +01:00
|
|
|
i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS) {
|
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("LSA[Refresh]: %s: refresh index %d",
|
|
|
|
__func__, i);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
refresh_list = ospf->lsa_refresh_queue.qs[i];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-13 23:33:54 +02:00
|
|
|
assert(i >= 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->lsa_refresh_queue.qs[i] = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (refresh_list) {
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(refresh_list, node, nnode,
|
2017-07-17 14:03:14 +02:00
|
|
|
lsa)) {
|
2002-12-13 22:44:27 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2015-03-03 08:51:53 +01:00
|
|
|
zlog_debug(
|
2022-08-24 19:56:16 +02:00
|
|
|
"LSA[Refresh:Type%d:%pI4]: %s: refresh lsa %p (slot %d)",
|
|
|
|
lsa->data->type, &lsa->data->id,
|
|
|
|
__func__, (void *)lsa, i);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-04-13 23:33:54 +02:00
|
|
|
assert(lsa->lock > 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
list_delete_node(refresh_list, node);
|
|
|
|
lsa->refresh_list = -1;
|
|
|
|
listnode_add(lsa_to_refresh, lsa);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&refresh_list);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
ospf->t_lsa_refresher = NULL;
|
2017-05-05 23:22:25 +02:00
|
|
|
thread_add_timer(master, ospf_lsa_refresh_walker, ospf,
|
|
|
|
ospf->lsa_refresh_interval, &ospf->t_lsa_refresher);
|
2017-01-18 01:30:43 +01:00
|
|
|
ospf->lsa_refresher_started = monotime(NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
for (ALL_LIST_ELEMENTS(lsa_to_refresh, node, nnode, lsa)) {
|
2022-11-21 13:50:16 +01:00
|
|
|
dna_lsa = ospf_check_dna_lsa(lsa);
|
|
|
|
if (!dna_lsa) { /* refresh only non-DNA LSAs */
|
|
|
|
ospf_lsa_refresh(ospf, lsa);
|
|
|
|
assert(lsa->lock > 0);
|
|
|
|
ospf_lsa_unlock(&lsa); /* lsa_refresh_queue & temp for
|
|
|
|
* lsa_to_refresh.
|
|
|
|
*/
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&lsa_to_refresh);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
|
2022-08-24 19:56:16 +02:00
|
|
|
zlog_debug("LSA[Refresh]: %s: end", __func__);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2020-10-18 13:49:32 +02:00
|
|
|
|
|
|
|
/* Flush the LSAs for the specific area */
|
|
|
|
void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
|
|
|
|
int type)
|
|
|
|
{
|
|
|
|
struct ospf_area *area;
|
|
|
|
struct route_node *rn;
|
|
|
|
struct ospf_lsa *lsa;
|
|
|
|
|
|
|
|
area = ospf_area_get(ospf, area_id);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case OSPF_AS_EXTERNAL_LSA:
|
|
|
|
if ((area->external_routing == OSPF_AREA_NSSA) ||
|
|
|
|
(area->external_routing == OSPF_AREA_STUB)) {
|
|
|
|
LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa) &&
|
|
|
|
!(CHECK_FLAG(lsa->flags,
|
|
|
|
OSPF_LSA_LOCAL_XLT)))
|
|
|
|
ospf_lsa_flush_area(lsa, area);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OSPF_AS_NSSA_LSA:
|
|
|
|
LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
|
|
|
|
if (IS_LSA_SELF(lsa))
|
|
|
|
ospf_lsa_flush_area(lsa, area);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|