#include "isisd/isis_memory.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_adjacency.h"
-#include "isisd/isis_tlv.h"
#include "isisd/isis_misc.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_mt.h"
-#include "isisd/isis_tlvs2.h"
+#include "isisd/isis_tlvs.h"
DEFINE_MTYPE_STATIC(ISISD, MT_AREA_SETTING, "ISIS MT Area Setting")
DEFINE_MTYPE_STATIC(ISISD, MT_CIRCUIT_SETTING, "ISIS MT Circuit Setting")
DEFINE_MTYPE_STATIC(ISISD, MT_ADJ_INFO, "ISIS MT Adjacency Info")
-DEFINE_MTYPE_STATIC(ISISD, MT_NEIGHBORS, "ISIS MT Neighbors for TLV")
-DEFINE_MTYPE_STATIC(ISISD, MT_IPV4_REACHS,
- "ISIS MT IPv4 Reachabilities for TLV")
-DEFINE_MTYPE_STATIC(ISISD, MT_IPV6_REACHS,
- "ISIS MT IPv6 Reachabilities for TLV")
+
+bool isis_area_ipv6_dstsrc_enabled(struct isis_area *area)
+{
+ struct isis_area_mt_setting *area_mt_setting;
+ area_mt_setting = area_lookup_mt_setting(area, ISIS_MT_IPV6_DSTSRC);
+
+ return (area_mt_setting && area_mt_setting->enabled);
+}
uint16_t isis_area_ipv6_topology(struct isis_area *area)
{
return "ipv6-multicast";
case ISIS_MT_IPV6_MGMT:
return "ipv6-mgmt";
+ case ISIS_MT_IPV6_DSTSRC:
+ return "ipv6-dstsrc";
default:
snprintf(buf, sizeof(buf), "%" PRIu16, mtid);
return buf;
return ISIS_MT_IPV6_MULTICAST;
if (!strcmp(name, "ipv6-mgmt"))
return ISIS_MT_IPV6_MGMT;
+ if (!strcmp(name, "ipv6-dstsrc"))
+ return ISIS_MT_IPV6_DSTSRC;
return -1;
}
void area_mt_finish(struct isis_area *area)
{
- list_delete(area->mt_settings);
- area->mt_settings = NULL;
+ list_delete(&area->mt_settings);
}
struct isis_area_mt_setting *area_get_mt_setting(struct isis_area *area,
void circuit_mt_finish(struct isis_circuit *circuit)
{
- list_delete(circuit->mt_settings);
- circuit->mt_settings = NULL;
+ list_delete(&circuit->mt_settings);
}
struct isis_circuit_mt_setting *
return setting;
}
-int circuit_write_mt_settings(struct isis_circuit *circuit, struct vty *vty)
+static int circuit_write_mt_settings(struct isis_circuit *circuit,
+ struct vty *vty)
{
int written = 0;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(circuit->mt_settings, node, setting)) {
const char *name = isis_mtid2str(setting->mtid);
if (name && !setting->enabled) {
- vty_out(vty, " no isis topology %s\n", name);
+ vty_out(vty, " no " PROTO_NAME " topology %s\n", name);
written++;
}
}
mt_settings = circuit_mt_settings(adj->circuit, &circuit_mt_count);
for (unsigned int i = 0; i < circuit_mt_count; i++) {
- if (tlvs->mt_router_info.count && !tlvs->mt_router_info_empty) {
+ if (!tlvs->mt_router_info.count
+ && !tlvs->mt_router_info_empty) {
/* Other end does not have MT enabled */
if (mt_settings[i]->mtid == ISIS_MT_IPV4_UNICAST
- && v4_usable)
+ && (v4_usable || v6_usable))
adj_mt_set(adj, intersect_count++,
ISIS_MT_IPV4_UNICAST);
} else {
adj->mt_count = 0;
}
-/* TLV Router info api */
-struct mt_router_info *tlvs_lookup_mt_router_info(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_router_info, mtid);
-}
-
-/* TLV MT Neighbors api */
-struct tlv_mt_neighbors *tlvs_lookup_mt_neighbors(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_is_neighs, mtid);
-}
-
-static struct tlv_mt_neighbors *tlvs_new_mt_neighbors(uint16_t mtid)
-{
- struct tlv_mt_neighbors *rv;
-
- rv = XCALLOC(MTYPE_MT_NEIGHBORS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_neighbors(void *arg)
-{
- struct tlv_mt_neighbors *neighbors = arg;
-
- if (neighbors && neighbors->list)
- list_delete(neighbors->list);
- XFREE(MTYPE_MT_NEIGHBORS, neighbors);
-}
-
-static void tlvs_add_mt_neighbors(struct tlvs *tlvs,
- struct tlv_mt_neighbors *neighbors)
-{
- add_mt_setting(&tlvs->mt_is_neighs, neighbors);
- tlvs->mt_is_neighs->del = tlvs_free_mt_neighbors;
-}
-
-struct tlv_mt_neighbors *tlvs_get_mt_neighbors(struct tlvs *tlvs, uint16_t mtid)
-{
- struct tlv_mt_neighbors *neighbors;
-
- neighbors = tlvs_lookup_mt_neighbors(tlvs, mtid);
- if (!neighbors) {
- neighbors = tlvs_new_mt_neighbors(mtid);
- tlvs_add_mt_neighbors(tlvs, neighbors);
- }
- return neighbors;
-}
-
-/* TLV MT IPv4 reach api */
-struct tlv_mt_ipv4_reachs *tlvs_lookup_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_ipv4_reachs, mtid);
-}
-
-static struct tlv_mt_ipv4_reachs *tlvs_new_mt_ipv4_reachs(uint16_t mtid)
-{
- struct tlv_mt_ipv4_reachs *rv;
-
- rv = XCALLOC(MTYPE_MT_IPV4_REACHS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_ipv4_reachs(void *arg)
-{
- struct tlv_mt_ipv4_reachs *reachs = arg;
-
- if (reachs && reachs->list)
- list_delete(reachs->list);
- XFREE(MTYPE_MT_IPV4_REACHS, reachs);
-}
-
-static void tlvs_add_mt_ipv4_reachs(struct tlvs *tlvs,
- struct tlv_mt_ipv4_reachs *reachs)
-{
- add_mt_setting(&tlvs->mt_ipv4_reachs, reachs);
- tlvs->mt_ipv4_reachs->del = tlvs_free_mt_ipv4_reachs;
-}
-
-struct tlv_mt_ipv4_reachs *tlvs_get_mt_ipv4_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- struct tlv_mt_ipv4_reachs *reachs;
-
- reachs = tlvs_lookup_mt_ipv4_reachs(tlvs, mtid);
- if (!reachs) {
- reachs = tlvs_new_mt_ipv4_reachs(mtid);
- tlvs_add_mt_ipv4_reachs(tlvs, reachs);
- }
- return reachs;
-}
-
-/* TLV MT IPv6 reach api */
-struct tlv_mt_ipv6_reachs *tlvs_lookup_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- return lookup_mt_setting(tlvs->mt_ipv6_reachs, mtid);
-}
-
-static struct tlv_mt_ipv6_reachs *tlvs_new_mt_ipv6_reachs(uint16_t mtid)
-{
- struct tlv_mt_ipv6_reachs *rv;
-
- rv = XCALLOC(MTYPE_MT_IPV6_REACHS, sizeof(*rv));
- rv->mtid = mtid;
- rv->list = list_new();
-
- return rv;
-};
-
-static void tlvs_free_mt_ipv6_reachs(void *arg)
-{
- struct tlv_mt_ipv6_reachs *reachs = arg;
-
- if (reachs && reachs->list)
- list_delete(reachs->list);
- XFREE(MTYPE_MT_IPV6_REACHS, reachs);
-}
-
-static void tlvs_add_mt_ipv6_reachs(struct tlvs *tlvs,
- struct tlv_mt_ipv6_reachs *reachs)
-{
- add_mt_setting(&tlvs->mt_ipv6_reachs, reachs);
- tlvs->mt_ipv6_reachs->del = tlvs_free_mt_ipv6_reachs;
-}
-
-struct tlv_mt_ipv6_reachs *tlvs_get_mt_ipv6_reachs(struct tlvs *tlvs,
- uint16_t mtid)
-{
- struct tlv_mt_ipv6_reachs *reachs;
-
- reachs = tlvs_lookup_mt_ipv6_reachs(tlvs, mtid);
- if (!reachs) {
- reachs = tlvs_new_mt_ipv6_reachs(mtid);
- tlvs_add_mt_ipv6_reachs(tlvs, reachs);
- }
- return reachs;
-}
-
static void mt_set_add(uint16_t **mt_set, unsigned int *size,
unsigned int *index, uint16_t mtid)
{
return rv;
}
-static void tlvs_add_mt_set(struct isis_area *area, struct tlvs *tlvs,
+static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs,
unsigned int mt_count, uint16_t *mt_set,
- struct te_is_neigh *neigh)
+ uint8_t *id, uint32_t metric,
+ struct isis_ext_subtlvs *ext)
{
for (unsigned int i = 0; i < mt_count; i++) {
uint16_t mtid = mt_set[i];
- struct te_is_neigh *ne_copy;
-
- ne_copy = XCALLOC(MTYPE_ISIS_TLV, sizeof(*ne_copy));
- memcpy(ne_copy, neigh, sizeof(*ne_copy));
-
if (mt_set[i] == ISIS_MT_IPV4_UNICAST) {
- listnode_add(tlvs->te_is_neighs, ne_copy);
lsp_debug(
"ISIS (%s): Adding %s.%02x as te-style neighbor",
- area->area_tag, sysid_print(ne_copy->neigh_id),
- LSP_PSEUDO_ID(ne_copy->neigh_id));
+ area->area_tag, sysid_print(id),
+ LSP_PSEUDO_ID(id));
} else {
- struct tlv_mt_neighbors *neighbors;
-
- neighbors = tlvs_get_mt_neighbors(tlvs, mtid);
- neighbors->list->del = free_tlv;
- listnode_add(neighbors->list, ne_copy);
lsp_debug(
"ISIS (%s): Adding %s.%02x as mt-style neighbor for %s",
- area->area_tag, sysid_print(ne_copy->neigh_id),
- LSP_PSEUDO_ID(ne_copy->neigh_id),
- isis_mtid2str(mtid));
+ area->area_tag, sysid_print(id),
+ LSP_PSEUDO_ID(id), isis_mtid2str(mtid));
}
+ isis_tlvs_add_extended_reach(tlvs, mtid, id, metric, ext);
}
}
-void tlvs_add_mt_bcast(struct tlvs *tlvs, struct isis_circuit *circuit,
- int level, struct te_is_neigh *neigh)
+void tlvs_add_mt_bcast(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ int level, uint8_t *id, uint32_t metric)
{
unsigned int mt_count;
uint16_t *mt_set = circuit_bcast_mt_set(circuit, level, &mt_count);
- tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, neigh);
+ tlvs_add_mt_set(circuit->area, tlvs, mt_count, mt_set, id, metric,
+ circuit->ext);
}
-void tlvs_add_mt_p2p(struct tlvs *tlvs, struct isis_circuit *circuit,
- struct te_is_neigh *neigh)
+void tlvs_add_mt_p2p(struct isis_tlvs *tlvs, struct isis_circuit *circuit,
+ uint8_t *id, uint32_t metric)
{
struct isis_adjacency *adj = circuit->u.p2p.neighbor;
- tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, neigh);
+ tlvs_add_mt_set(circuit->area, tlvs, adj->mt_count, adj->mt_set, id,
+ metric, circuit->ext);
+}
+
+void mt_init(void)
+{
+ hook_register(isis_circuit_config_write,
+ circuit_write_mt_settings);
}