mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-11-02 23:52:33 +00:00
isisd: add purge originator identification support
Implement RFC 6232, optionally allowing to flood isisd's NET and hostname in purges it originates. Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
5f77d90188
commit
2c92bee499
@ -106,6 +106,14 @@ writing, *isisd* does not support multiple ISIS processes.
|
||||
|
||||
Set overload bit to avoid any transit traffic.
|
||||
|
||||
.. index:: purge-originator
|
||||
.. clicmd:: purge-originator
|
||||
|
||||
.. index:: no purge-originator
|
||||
.. clicmd:: no purge-originator
|
||||
|
||||
Enable or disable :rfc:`6232` purge originator identification.
|
||||
|
||||
.. _isis-timer:
|
||||
|
||||
ISIS Timer
|
||||
|
||||
@ -353,7 +353,21 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno)
|
||||
isis_spf_schedule(lsp->area, lsp->level);
|
||||
}
|
||||
|
||||
static void lsp_purge(struct isis_lsp *lsp, int level)
|
||||
static void lsp_purge_add_poi(struct isis_lsp *lsp,
|
||||
const uint8_t *sender)
|
||||
{
|
||||
if (!lsp->area->purge_originator)
|
||||
return;
|
||||
|
||||
/* add purge originator identification */
|
||||
if (!lsp->tlvs)
|
||||
lsp->tlvs = isis_alloc_tlvs();
|
||||
isis_tlvs_set_purge_originator(lsp->tlvs, isis->sysid, sender);
|
||||
isis_tlvs_set_dynamic_hostname(lsp->tlvs, cmd_hostname_get());
|
||||
}
|
||||
|
||||
static void lsp_purge(struct isis_lsp *lsp, int level,
|
||||
const uint8_t *sender)
|
||||
{
|
||||
/* reset stream */
|
||||
lsp_clear_data(lsp);
|
||||
@ -365,6 +379,8 @@ static void lsp_purge(struct isis_lsp *lsp, int level)
|
||||
lsp->level = level;
|
||||
lsp->age_out = lsp->area->max_lsp_lifetime[level - 1];
|
||||
|
||||
lsp_purge_add_poi(lsp, sender);
|
||||
|
||||
lsp_pack_pdu(lsp);
|
||||
lsp_flood(lsp, NULL);
|
||||
}
|
||||
@ -386,7 +402,7 @@ static void lsp_seqno_update(struct isis_lsp *lsp0)
|
||||
if (lsp->tlvs)
|
||||
lsp_inc_seqno(lsp, 0);
|
||||
else
|
||||
lsp_purge(lsp, lsp0->level);
|
||||
lsp_purge(lsp, lsp0->level, NULL);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -426,7 +442,8 @@ static void lsp_update_data(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
||||
|
||||
lsp->tlvs = tlvs;
|
||||
|
||||
if (area->dynhostname && lsp->tlvs->hostname) {
|
||||
if (area->dynhostname && lsp->tlvs->hostname
|
||||
&& lsp->hdr.rem_lifetime) {
|
||||
isis_dynhn_insert(lsp->hdr.lsp_id, lsp->tlvs->hostname,
|
||||
(lsp->hdr.lsp_bits & LSPBIT_IST)
|
||||
== IS_LEVEL_1_AND_2
|
||||
@ -463,10 +480,10 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
|
||||
lsp->own_lsp = 0;
|
||||
}
|
||||
|
||||
lsp_update_data(lsp, hdr, tlvs, stream, area, level);
|
||||
if (confusion) {
|
||||
lsp->hdr.rem_lifetime = hdr->rem_lifetime = 0;
|
||||
put_lsp_hdr(lsp, NULL, true);
|
||||
lsp_purge(lsp, level, NULL);
|
||||
} else {
|
||||
lsp_update_data(lsp, hdr, tlvs, stream, area, level);
|
||||
}
|
||||
|
||||
if (LSP_FRAGMENT(lsp->hdr.lsp_id) && !lsp->lspu.zero_lsp) {
|
||||
@ -1865,17 +1882,14 @@ int lsp_tick(struct thread *thread)
|
||||
*/
|
||||
if (rem_lifetime == 1 && lsp->hdr.seqno != 0) {
|
||||
/* 7.3.16.4 a) set SRM flags on all */
|
||||
lsp_flood(lsp, NULL);
|
||||
/* 7.3.16.4 b) retain only the header
|
||||
* FIXME */
|
||||
/* 7.3.16.4 b) retain only the header */
|
||||
if (lsp->area->purge_originator)
|
||||
lsp_purge(lsp, lsp->level, NULL);
|
||||
else
|
||||
lsp_flood(lsp, NULL);
|
||||
/* 7.3.16.4 c) record the time to purge
|
||||
* FIXME */
|
||||
/* run/schedule spf */
|
||||
/* isis_spf_schedule is called inside
|
||||
* lsp_destroy() below;
|
||||
* so it is not needed here. */
|
||||
/* isis_spf_schedule (lsp->area,
|
||||
* lsp->level); */
|
||||
isis_spf_schedule(lsp->area, lsp->level);
|
||||
}
|
||||
|
||||
if (lsp->age_out == 0) {
|
||||
@ -1917,7 +1931,7 @@ void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level)
|
||||
if (!lsp)
|
||||
return;
|
||||
|
||||
lsp_purge(lsp, level);
|
||||
lsp_purge(lsp, level, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1941,6 +1955,8 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
|
||||
memcpy(&lsp->hdr, hdr, sizeof(lsp->hdr));
|
||||
lsp->hdr.rem_lifetime = 0;
|
||||
|
||||
lsp_purge_add_poi(lsp, NULL);
|
||||
|
||||
lsp_pack_pdu(lsp);
|
||||
|
||||
lsp_insert(lsp, area->lspdb[lsp->level - 1]);
|
||||
|
||||
@ -900,7 +900,8 @@ dontcheckadj:
|
||||
* but
|
||||
* wrong checksum, initiate a purge. */
|
||||
if (lsp && (lsp->hdr.seqno == hdr.seqno)
|
||||
&& (lsp->hdr.checksum != hdr.checksum)) {
|
||||
&& (lsp->hdr.checksum != hdr.checksum)
|
||||
&& hdr.rem_lifetime) {
|
||||
zlog_warn("ISIS-Upd (%s): LSP %s seq 0x%08" PRIx32
|
||||
" with confused checksum received.",
|
||||
circuit->area->area_tag, rawlspid_print(hdr.lsp_id),
|
||||
|
||||
@ -3697,3 +3697,20 @@ isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs,
|
||||
const uint8_t *generator,
|
||||
const uint8_t *sender)
|
||||
{
|
||||
assert(!tlvs->purge_originator);
|
||||
|
||||
tlvs->purge_originator = XCALLOC(MTYPE_ISIS_TLV,
|
||||
sizeof(*tlvs->purge_originator));
|
||||
memcpy(tlvs->purge_originator->generator, generator,
|
||||
sizeof(tlvs->purge_originator->generator));
|
||||
if (sender) {
|
||||
tlvs->purge_originator->sender_set = true;
|
||||
memcpy(tlvs->purge_originator->sender, sender,
|
||||
sizeof(tlvs->purge_originator->sender));
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,4 +383,8 @@ void isis_tlvs_add_spine_leaf(struct isis_tlvs *tlvs, uint8_t tier,
|
||||
|
||||
struct isis_mt_router_info *
|
||||
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid);
|
||||
|
||||
void isis_tlvs_set_purge_originator(struct isis_tlvs *tlvs,
|
||||
const uint8_t *generator,
|
||||
const uint8_t *sender);
|
||||
#endif
|
||||
|
||||
@ -568,6 +568,18 @@ DEFUN (no_area_lsp_mtu,
|
||||
return isis_vty_lsp_mtu_set(vty, DEFAULT_LSP_MTU);
|
||||
}
|
||||
|
||||
DEFUN (area_purge_originator,
|
||||
area_purge_originator_cmd,
|
||||
"[no] purge-originator",
|
||||
NO_STR
|
||||
"Use the RFC 6232 purge-originator\n")
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(isis_area, area);
|
||||
|
||||
area->purge_originator = !!strcmp(argv[0]->text, "no");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int isis_vty_lsp_gen_interval_set(struct vty *vty, int level, uint16_t interval)
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(isis_area, area);
|
||||
@ -924,6 +936,8 @@ void isis_vty_init(void)
|
||||
install_element(ROUTER_NODE, &area_lsp_mtu_cmd);
|
||||
install_element(ROUTER_NODE, &no_area_lsp_mtu_cmd);
|
||||
|
||||
install_element(ROUTER_NODE, &area_purge_originator_cmd);
|
||||
|
||||
install_element(ROUTER_NODE, &lsp_gen_interval_cmd);
|
||||
install_element(ROUTER_NODE, &no_lsp_gen_interval_cmd);
|
||||
|
||||
|
||||
@ -2029,6 +2029,10 @@ int isis_config_write(struct vty *vty)
|
||||
vty_out(vty, " lsp-mtu %u\n", area->lsp_mtu);
|
||||
write++;
|
||||
}
|
||||
if (area->purge_originator) {
|
||||
vty_out(vty, " purge-originator\n");
|
||||
write++;
|
||||
}
|
||||
|
||||
/* Minimum SPF interval. */
|
||||
if (area->min_spf_interval[0]
|
||||
|
||||
@ -148,6 +148,7 @@ struct isis_area {
|
||||
/* multi topology settings */
|
||||
struct list *mt_settings;
|
||||
int ipv6_circuits;
|
||||
bool purge_originator;
|
||||
/* Counters */
|
||||
uint32_t circuit_state_changes;
|
||||
struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user