]> git.puffer.fish Git - mirror/frr.git/commitdiff
isisd: add purge originator identification support
authorChristian Franke <chris@opensourcerouting.org>
Thu, 31 May 2018 13:14:26 +0000 (15:14 +0200)
committerChristian Franke <chris@opensourcerouting.org>
Wed, 5 Sep 2018 09:38:13 +0000 (11:38 +0200)
Implement RFC 6232, optionally allowing to flood isisd's NET and
hostname in purges it originates.

Signed-off-by: Christian Franke <chris@opensourcerouting.org>
doc/user/isisd.rst
isisd/isis_lsp.c
isisd/isis_pdu.c
isisd/isis_tlvs.c
isisd/isis_tlvs.h
isisd/isis_vty_common.c
isisd/isisd.c
isisd/isisd.h

index 54f82f683255836bfccf4bd4e167658aafdb606b..ee681858d1a4bc6f8590039fcf8c9178f6c9282f 100644 (file)
@@ -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
index dc387379239f865cf0d07e330a1e00db97db935d..e8777e9b53a1d6eaab1e706e77058e2771f401f9 100644 (file)
@@ -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]);
index ce050a0c93811cb23ff1ecb3a3c21befed231e11..8649c5a0c8930f6e5613ac6e83e4e9482f84a55b 100644 (file)
@@ -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),
index 0efe52d0c119393a295d19a87fb9fad80a21b2ea..b22460a0b5402abb914d1a45ea26aec402a114e4 100644 (file)
@@ -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));
+       }
+}
index abdd03f02ddd461a9356265b4e97da39aaaf8f87..4144809fa3aeaaf4a55317dfe522679906ae3705 100644 (file)
@@ -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
index dbe5beca6e72afbc607c970dabefcd67635f894a..2b98a88b342233637799b33412041c61b9df185c 100644 (file)
@@ -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);
 
index 640bd69ce4536c4c14786130aea77e5756f0c43d..e3ff3b8d93e377111a666099048a991ef9212319 100644 (file)
@@ -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]
index cc5def8f56f2a048bed160f68f2f8fa59f793308..864021428aa885dfbf07d3eae33e98dec79f4ed7 100644 (file)
@@ -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]