mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-05 16:57:44 +00:00
isisd: add support for TLV 240 P2P Three-Way Adjacency
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
This commit is contained in:
parent
9703538621
commit
9fe2120814
@ -1329,6 +1329,119 @@ static int unpack_tlv_dynamic_hostname(enum isis_tlv_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Functions related to TLV 240 P2P Three-Way Adjacency */
|
||||
|
||||
const char *isis_threeway_state_name(enum isis_threeway_state state)
|
||||
{
|
||||
switch (state) {
|
||||
case ISIS_THREEWAY_DOWN:
|
||||
return "Down";
|
||||
case ISIS_THREEWAY_INITIALIZING:
|
||||
return "Initializing";
|
||||
case ISIS_THREEWAY_UP:
|
||||
return "Up";
|
||||
default:
|
||||
return "Invalid!";
|
||||
}
|
||||
}
|
||||
|
||||
static struct isis_threeway_adj *copy_tlv_threeway_adj(
|
||||
const struct isis_threeway_adj *threeway_adj)
|
||||
{
|
||||
if (!threeway_adj)
|
||||
return NULL;
|
||||
|
||||
struct isis_threeway_adj *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
|
||||
memcpy(rv, threeway_adj, sizeof(*rv));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void format_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj,
|
||||
struct sbuf *buf, int indent)
|
||||
{
|
||||
if (!threeway_adj)
|
||||
return;
|
||||
|
||||
sbuf_push(buf, indent, "P2P Three-Way Adjacency:\n");
|
||||
sbuf_push(buf, indent, " State: %s (%d)\n",
|
||||
isis_threeway_state_name(threeway_adj->state),
|
||||
threeway_adj->state);
|
||||
sbuf_push(buf, indent, " Extended Local Circuit ID: %" PRIu32 "\n",
|
||||
threeway_adj->local_circuit_id);
|
||||
if (!threeway_adj->neighbor_set)
|
||||
return;
|
||||
|
||||
sbuf_push(buf, indent, " Neighbor System ID: %s\n",
|
||||
isis_format_id(threeway_adj->neighbor_id, 6));
|
||||
sbuf_push(buf, indent, " Neighbor Extended Circuit ID: %" PRIu32 "\n",
|
||||
threeway_adj->neighbor_circuit_id);
|
||||
}
|
||||
|
||||
static void free_tlv_threeway_adj(struct isis_threeway_adj *threeway_adj)
|
||||
{
|
||||
XFREE(MTYPE_ISIS_TLV, threeway_adj);
|
||||
}
|
||||
|
||||
static int pack_tlv_threeway_adj(const struct isis_threeway_adj *threeway_adj,
|
||||
struct stream *s)
|
||||
{
|
||||
if (!threeway_adj)
|
||||
return 0;
|
||||
|
||||
uint8_t tlv_len = (threeway_adj->neighbor_set) ? 15 : 5;
|
||||
|
||||
if (STREAM_WRITEABLE(s) < (unsigned)(2 + tlv_len))
|
||||
return 1;
|
||||
|
||||
stream_putc(s, ISIS_TLV_THREE_WAY_ADJ);
|
||||
stream_putc(s, tlv_len);
|
||||
stream_putc(s, threeway_adj->state);
|
||||
stream_putl(s, threeway_adj->local_circuit_id);
|
||||
|
||||
if (threeway_adj->neighbor_set) {
|
||||
stream_put(s, threeway_adj->neighbor_id, 6);
|
||||
stream_putl(s, threeway_adj->neighbor_circuit_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpack_tlv_threeway_adj(enum isis_tlv_context context,
|
||||
uint8_t tlv_type, uint8_t tlv_len,
|
||||
struct stream *s, struct sbuf *log,
|
||||
void *dest, int indent)
|
||||
{
|
||||
struct isis_tlvs *tlvs = dest;
|
||||
|
||||
sbuf_push(log, indent, "Unpacking P2P Three-Way Adjacency TLV...\n");
|
||||
if (tlv_len != 5 && tlv_len != 15) {
|
||||
sbuf_push(log, indent, "WARNING: Unexepected TLV size\n");
|
||||
stream_forward_getp(s, tlv_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tlvs->threeway_adj) {
|
||||
sbuf_push(log, indent,
|
||||
"WARNING: P2P Three-Way Adjacency TLV present multiple times.\n");
|
||||
stream_forward_getp(s, tlv_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
tlvs->threeway_adj = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->threeway_adj));
|
||||
|
||||
tlvs->threeway_adj->state = stream_getc(s);
|
||||
tlvs->threeway_adj->local_circuit_id = stream_getl(s);
|
||||
|
||||
if (tlv_len == 15) {
|
||||
tlvs->threeway_adj->neighbor_set = true;
|
||||
stream_get(tlvs->threeway_adj->neighbor_id, s, 6);
|
||||
tlvs->threeway_adj->neighbor_circuit_id = stream_getl(s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Functions related to TLVs 236/237 IPv6/MT-IPv6 reach */
|
||||
|
||||
static struct isis_item *copy_item_ipv6_reach(struct isis_item *i)
|
||||
@ -2067,6 +2180,8 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs)
|
||||
copy_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH,
|
||||
&tlvs->mt_ipv6_reach, &rv->mt_ipv6_reach);
|
||||
|
||||
rv->threeway_adj = copy_tlv_threeway_adj(tlvs->threeway_adj);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2128,6 +2243,8 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent)
|
||||
|
||||
format_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH,
|
||||
&tlvs->mt_ipv6_reach, buf, indent);
|
||||
|
||||
format_tlv_threeway_adj(tlvs->threeway_adj, buf, indent);
|
||||
}
|
||||
|
||||
const char *isis_format_tlvs(struct isis_tlvs *tlvs)
|
||||
@ -2178,6 +2295,7 @@ void isis_free_tlvs(struct isis_tlvs *tlvs)
|
||||
free_items(ISIS_CONTEXT_LSP, ISIS_TLV_IPV6_REACH, &tlvs->ipv6_reach);
|
||||
free_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IPV6_REACH,
|
||||
&tlvs->mt_ipv6_reach);
|
||||
free_tlv_threeway_adj(tlvs->threeway_adj);
|
||||
|
||||
XFREE(MTYPE_ISIS_TLV, tlvs);
|
||||
}
|
||||
@ -2349,6 +2467,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream,
|
||||
copy_tlv_te_router_id(tlvs->te_router_id);
|
||||
}
|
||||
|
||||
rv = pack_tlv_threeway_adj(tlvs->threeway_adj, stream);
|
||||
if (rv)
|
||||
return rv;
|
||||
if (fragment_tlvs) {
|
||||
fragment_tlvs->threeway_adj =
|
||||
copy_tlv_threeway_adj(tlvs->threeway_adj);
|
||||
}
|
||||
|
||||
for (size_t pack_idx = 0; pack_idx < array_size(pack_order);
|
||||
pack_idx++) {
|
||||
rv = handle_pack_entry(&pack_order[pack_idx], tlvs, stream,
|
||||
@ -2549,6 +2675,7 @@ TLV_OPS(te_router_id, "TLV 134 TE Router ID");
|
||||
ITEM_TLV_OPS(extended_ip_reach, "TLV 135 Extended IP Reachability");
|
||||
TLV_OPS(dynamic_hostname, "TLV 137 Dynamic Hostname");
|
||||
ITEM_TLV_OPS(mt_router_info, "TLV 229 MT Router Information");
|
||||
TLV_OPS(threeway_adj, "TLV 240 P2P Three-Way Adjacency");
|
||||
ITEM_TLV_OPS(ipv6_address, "TLV 232 IPv6 Interface Address");
|
||||
ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability");
|
||||
|
||||
@ -2572,6 +2699,7 @@ static const struct tlv_ops *tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = {
|
||||
[ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops,
|
||||
[ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops,
|
||||
[ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops,
|
||||
[ISIS_TLV_THREE_WAY_ADJ] = &tlv_threeway_adj_ops,
|
||||
[ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops,
|
||||
[ISIS_TLV_IPV6_REACH] = &tlv_ipv6_reach_ops,
|
||||
[ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops,
|
||||
@ -3072,6 +3200,25 @@ void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
append_item(l, (struct isis_item *)r);
|
||||
}
|
||||
|
||||
void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs,
|
||||
enum isis_threeway_state state,
|
||||
uint32_t local_circuit_id,
|
||||
const uint8_t *neighbor_id,
|
||||
uint32_t neighbor_circuit_id)
|
||||
{
|
||||
assert(!tlvs->threeway_adj);
|
||||
|
||||
tlvs->threeway_adj = XCALLOC(MTYPE_ISIS_TLV, sizeof(*tlvs->threeway_adj));
|
||||
tlvs->threeway_adj->state = state;
|
||||
tlvs->threeway_adj->local_circuit_id = local_circuit_id;
|
||||
|
||||
if (neighbor_id) {
|
||||
tlvs->threeway_adj->neighbor_set = true;
|
||||
memcpy(tlvs->threeway_adj->neighbor_id, neighbor_id, 6);
|
||||
tlvs->threeway_adj->neighbor_circuit_id = neighbor_circuit_id;
|
||||
}
|
||||
}
|
||||
|
||||
struct isis_mt_router_info *
|
||||
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid)
|
||||
{
|
||||
|
@ -103,6 +103,20 @@ struct isis_protocols_supported {
|
||||
uint8_t *protocols;
|
||||
};
|
||||
|
||||
enum isis_threeway_state {
|
||||
ISIS_THREEWAY_DOWN = 2,
|
||||
ISIS_THREEWAY_INITIALIZING = 1,
|
||||
ISIS_THREEWAY_UP = 0
|
||||
};
|
||||
|
||||
struct isis_threeway_adj {
|
||||
enum isis_threeway_state state;
|
||||
uint32_t local_circuit_id;
|
||||
bool neighbor_set;
|
||||
uint8_t neighbor_id[6];
|
||||
uint32_t neighbor_circuit_id;
|
||||
};
|
||||
|
||||
struct isis_item;
|
||||
struct isis_item {
|
||||
struct isis_item *next;
|
||||
@ -190,6 +204,7 @@ struct isis_tlvs {
|
||||
char *hostname;
|
||||
struct isis_item_list ipv6_reach;
|
||||
struct isis_mt_item_list mt_ipv6_reach;
|
||||
struct isis_threeway_adj *threeway_adj;
|
||||
};
|
||||
|
||||
struct isis_subtlvs {
|
||||
@ -227,6 +242,7 @@ enum isis_tlv_type {
|
||||
ISIS_TLV_MT_IP_REACH = 235,
|
||||
ISIS_TLV_IPV6_REACH = 236,
|
||||
ISIS_TLV_MT_IPV6_REACH = 237,
|
||||
ISIS_TLV_THREE_WAY_ADJ = 240,
|
||||
ISIS_TLV_MAX = 256,
|
||||
|
||||
ISIS_SUBTLV_IPV6_SOURCE_PREFIX = 22
|
||||
@ -303,6 +319,14 @@ void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid,
|
||||
uint8_t *id, uint32_t metric,
|
||||
uint8_t *subtlvs, uint8_t subtlv_len);
|
||||
|
||||
const char *isis_threeway_state_name(enum isis_threeway_state state);
|
||||
|
||||
void isis_tlvs_add_threeway_adj(struct isis_tlvs *tlvs,
|
||||
enum isis_threeway_state state,
|
||||
uint32_t local_circuit_id,
|
||||
const uint8_t *neighbor_id,
|
||||
uint32_t neighbor_circuit_id);
|
||||
|
||||
struct isis_mt_router_info *
|
||||
isis_tlvs_lookup_mt_router_info(struct isis_tlvs *tlvs, uint16_t mtid);
|
||||
#endif
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user