mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-04 20:02:42 +00:00
lib: Update Link State functions to handle IPv6
In order to add Link State Traffic Engineering to IS-IS, Link State library should have been updated: - Correct Node and Edge RB Tree comparison functions to support key > 32 bits - Change Subnet RB Tree comparison function to take into account host part of the prefix i.e. 10.0.0.1/24 and 10.0.0.2/24 are considered as different - Add new function to convert IS-IS ISO system ID into Vertex or Edge key that take into account Endianness architecture - Correct Vertex and Edge creation and search function accordingly - Add extra Adjacency entries in Link State Attributes for IPv6 Segment Routing - Update send/received and show TED functions accordingly Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
This commit is contained in:
parent
173f8887cc
commit
8693b4d66e
341
lib/link_state.c
341
lib/link_state.c
@ -89,7 +89,7 @@ struct ls_node *ls_node_new(struct ls_node_id adv, struct in_addr rid,
|
||||
}
|
||||
}
|
||||
if (!IN6_IS_ADDR_UNSPECIFIED(&rid6)) {
|
||||
new->router6_id = rid6;
|
||||
new->router_id6 = rid6;
|
||||
SET_FLAG(new->flags, LS_NODE_ROUTER_ID6);
|
||||
}
|
||||
return new;
|
||||
@ -127,7 +127,7 @@ int ls_node_same(struct ls_node *n1, struct ls_node *n2)
|
||||
&& !IPV4_ADDR_SAME(&n1->router_id, &n2->router_id))
|
||||
return 0;
|
||||
if (CHECK_FLAG(n1->flags, LS_NODE_ROUTER_ID6)
|
||||
&& !IPV6_ADDR_SAME(&n1->router6_id, &n2->router6_id))
|
||||
&& !IPV6_ADDR_SAME(&n1->router_id6, &n2->router_id6))
|
||||
return 0;
|
||||
if (CHECK_FLAG(n1->flags, LS_NODE_FLAG)
|
||||
&& (n1->node_flag != n2->node_flag))
|
||||
@ -306,36 +306,23 @@ int ls_attributes_same(struct ls_attributes *l1, struct ls_attributes *l2)
|
||||
if (CHECK_FLAG(l1->flags, LS_ATTR_USE_BW)
|
||||
&& (l1->extended.used_bw != l2->extended.used_bw))
|
||||
return 0;
|
||||
if (CHECK_FLAG(l1->flags, LS_ATTR_ADJ_SID)) {
|
||||
if ((l1->adj_sid[0].sid != l2->adj_sid[0].sid)
|
||||
|| (l1->adj_sid[0].flags != l2->adj_sid[0].flags)
|
||||
|| (l1->adj_sid[0].weight != l2->adj_sid[0].weight))
|
||||
for (int i = 0; i < LS_ADJ_MAX; i++) {
|
||||
if (!CHECK_FLAG(l1->flags, (LS_ATTR_ADJ_SID << i)))
|
||||
continue;
|
||||
if ((l1->adj_sid[i].sid != l2->adj_sid[i].sid)
|
||||
|| (l1->adj_sid[i].flags != l2->adj_sid[i].flags)
|
||||
|| (l1->adj_sid[i].weight != l2->adj_sid[i].weight))
|
||||
return 0;
|
||||
if (((l1->adv.origin == ISIS_L1) || (l1->adv.origin == ISIS_L2))
|
||||
&& (memcmp(&l1->adj_sid[0].neighbor.sysid,
|
||||
&l2->adj_sid[0].neighbor.sysid, ISO_SYS_ID_LEN)
|
||||
&& (memcmp(&l1->adj_sid[i].neighbor.sysid,
|
||||
&l2->adj_sid[i].neighbor.sysid, ISO_SYS_ID_LEN)
|
||||
!= 0))
|
||||
return 0;
|
||||
if (((l1->adv.origin == OSPFv2) || (l1->adv.origin == STATIC)
|
||||
|| (l1->adv.origin == DIRECT))
|
||||
&& (!IPV4_ADDR_SAME(&l1->adj_sid[0].neighbor.addr,
|
||||
&l2->adj_sid[0].neighbor.addr)))
|
||||
return 0;
|
||||
}
|
||||
if (CHECK_FLAG(l1->flags, LS_ATTR_BCK_ADJ_SID)) {
|
||||
if ((l1->adj_sid[1].sid != l2->adj_sid[1].sid)
|
||||
|| (l1->adj_sid[1].flags != l2->adj_sid[1].flags)
|
||||
|| (l1->adj_sid[1].weight != l2->adj_sid[1].weight))
|
||||
return 0;
|
||||
if (((l1->adv.origin == ISIS_L1) || (l1->adv.origin == ISIS_L2))
|
||||
&& (memcmp(&l1->adj_sid[1].neighbor.sysid,
|
||||
&l2->adj_sid[1].neighbor.sysid, ISO_SYS_ID_LEN)
|
||||
!= 0))
|
||||
return 0;
|
||||
if (((l1->adv.origin == OSPFv2) || (l1->adv.origin == STATIC)
|
||||
|| (l1->adv.origin == DIRECT))
|
||||
&& (!IPV4_ADDR_SAME(&l1->adj_sid[1].neighbor.addr,
|
||||
&l2->adj_sid[1].neighbor.addr)))
|
||||
&& (i < ADJ_PRI_IPV6)
|
||||
&& (!IPV4_ADDR_SAME(&l1->adj_sid[i].neighbor.addr,
|
||||
&l2->adj_sid[i].neighbor.addr)))
|
||||
return 0;
|
||||
}
|
||||
if (CHECK_FLAG(l1->flags, LS_ATTR_SRLG)
|
||||
@ -417,6 +404,25 @@ int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2)
|
||||
/**
|
||||
* Link State Vertices management functions
|
||||
*/
|
||||
uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN])
|
||||
{
|
||||
uint64_t key = 0;
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
uint8_t *byte = (uint8_t *)&key;
|
||||
|
||||
for (int i = 0; i < ISO_SYS_ID_LEN; i++)
|
||||
byte[i] = sysid[ISO_SYS_ID_LEN - i - 1];
|
||||
|
||||
byte[6] = 0;
|
||||
byte[7] = 0;
|
||||
#else
|
||||
memcpy(&key, sysid, ISO_SYS_ID_LEN);
|
||||
#endif
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
struct ls_vertex *ls_vertex_add(struct ls_ted *ted, struct ls_node *node)
|
||||
{
|
||||
struct ls_vertex *new;
|
||||
@ -435,7 +441,7 @@ struct ls_vertex *ls_vertex_add(struct ls_ted *ted, struct ls_node *node)
|
||||
break;
|
||||
case ISIS_L1:
|
||||
case ISIS_L2:
|
||||
memcpy(&key, &node->adv.id.iso.sys_id, ISO_SYS_ID_LEN);
|
||||
key = sysid_to_key(node->adv.id.iso.sys_id);
|
||||
break;
|
||||
default:
|
||||
key = 0;
|
||||
@ -557,7 +563,7 @@ struct ls_vertex *ls_find_vertex_by_id(struct ls_ted *ted,
|
||||
break;
|
||||
case ISIS_L1:
|
||||
case ISIS_L2:
|
||||
memcpy(&vertex.key, &nid.id.iso.sys_id, ISO_SYS_ID_LEN);
|
||||
vertex.key = sysid_to_key(nid.id.iso.sys_id);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
@ -673,6 +679,46 @@ static void ls_edge_connect_to(struct ls_ted *ted, struct ls_edge *edge)
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t get_edge_key(struct ls_attributes *attr, bool dst)
|
||||
{
|
||||
uint64_t key = 0;
|
||||
struct ls_standard *std;
|
||||
|
||||
if (!attr)
|
||||
return key;
|
||||
|
||||
std = &attr->standard;
|
||||
|
||||
if (dst) {
|
||||
/* Key is the IPv4 remote address */
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR))
|
||||
key = ((uint64_t)ntohl(std->remote.s_addr))
|
||||
& 0xffffffff;
|
||||
/* or the 64 bits LSB of IPv6 remote address */
|
||||
else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6))
|
||||
key = ((uint64_t)ntohl(std->remote6.s6_addr32[2]) << 32
|
||||
| (uint64_t)ntohl(std->remote6.s6_addr32[3]));
|
||||
/* of remote identifier if no IP addresses are defined */
|
||||
else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID))
|
||||
key = (((uint64_t)std->remote_id) & 0xffffffff)
|
||||
| ((uint64_t)std->local_id << 32);
|
||||
} else {
|
||||
/* Key is the IPv4 local address */
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
|
||||
key = ((uint64_t)ntohl(std->local.s_addr)) & 0xffffffff;
|
||||
/* or the 64 bits LSB of IPv6 local address */
|
||||
else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
|
||||
key = ((uint64_t)ntohl(std->local6.s6_addr32[2]) << 32
|
||||
| (uint64_t)ntohl(std->local6.s6_addr32[3]));
|
||||
/* of local identifier if no IP addresses are defined */
|
||||
else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
|
||||
key = (((uint64_t)std->local_id) & 0xffffffff)
|
||||
| ((uint64_t)std->remote_id << 32);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
struct ls_edge *ls_edge_add(struct ls_ted *ted,
|
||||
struct ls_attributes *attributes)
|
||||
{
|
||||
@ -682,23 +728,7 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted,
|
||||
if (attributes == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Key is the IPv4 local address */
|
||||
if (!IPV4_NET0(attributes->standard.local.s_addr))
|
||||
key = ((uint64_t)ntohl(attributes->standard.local.s_addr))
|
||||
& 0xffffffff;
|
||||
/* or the IPv6 local address if IPv4 is not defined */
|
||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.local6))
|
||||
key = (uint64_t)(attributes->standard.local6.s6_addr32[0]
|
||||
& 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.local6.s6_addr32[1]
|
||||
<< 32);
|
||||
/* of local identifier if no IP addresses are defined */
|
||||
else if (attributes->standard.local_id != 0)
|
||||
key = (uint64_t)(
|
||||
(attributes->standard.local_id & 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.remote_id << 32));
|
||||
|
||||
/* Check that key is valid */
|
||||
key = get_edge_key(attributes, false);
|
||||
if (key == 0)
|
||||
return NULL;
|
||||
|
||||
@ -736,23 +766,7 @@ struct ls_edge *ls_find_edge_by_source(struct ls_ted *ted,
|
||||
if (attributes == NULL)
|
||||
return NULL;
|
||||
|
||||
edge.key = 0;
|
||||
/* Key is the IPv4 local address */
|
||||
if (!IPV4_NET0(attributes->standard.local.s_addr))
|
||||
edge.key = ((uint64_t)ntohl(attributes->standard.local.s_addr))
|
||||
& 0xffffffff;
|
||||
/* or the IPv6 local address if IPv4 is not defined */
|
||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.local6))
|
||||
edge.key = (uint64_t)(attributes->standard.local6.s6_addr32[0]
|
||||
& 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.local6.s6_addr32[1]
|
||||
<< 32);
|
||||
/* of local identifier if no IP addresses are defined */
|
||||
else if (attributes->standard.local_id != 0)
|
||||
edge.key = (uint64_t)(
|
||||
(attributes->standard.local_id & 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.remote_id << 32));
|
||||
|
||||
edge.key = get_edge_key(attributes, false);
|
||||
if (edge.key == 0)
|
||||
return NULL;
|
||||
|
||||
@ -767,24 +781,7 @@ struct ls_edge *ls_find_edge_by_destination(struct ls_ted *ted,
|
||||
if (attributes == NULL)
|
||||
return NULL;
|
||||
|
||||
edge.key = 0;
|
||||
/* Key is the IPv4 remote address */
|
||||
if (!IPV4_NET0(attributes->standard.remote.s_addr))
|
||||
edge.key = ((uint64_t)ntohl(attributes->standard.remote.s_addr))
|
||||
& 0xffffffff;
|
||||
/* or the IPv6 remote address if IPv4 is not defined */
|
||||
else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.remote6))
|
||||
edge.key =
|
||||
(uint64_t)(attributes->standard.remote6.s6_addr32[0]
|
||||
& 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.remote6.s6_addr32[1]
|
||||
<< 32);
|
||||
/* of remote identifier if no IP addresses are defined */
|
||||
else if (attributes->standard.remote_id != 0)
|
||||
edge.key = (uint64_t)(
|
||||
(attributes->standard.remote_id & 0xffffffff)
|
||||
| ((uint64_t)attributes->standard.local_id << 32));
|
||||
|
||||
edge.key = get_edge_key(attributes, true);
|
||||
if (edge.key == 0)
|
||||
return NULL;
|
||||
|
||||
@ -1177,7 +1174,7 @@ static struct ls_node *ls_parse_node(struct stream *s)
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
|
||||
node->router_id.s_addr = stream_get_ipv4(s);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
|
||||
STREAM_GET(&node->router6_id, s, IPV6_MAX_BYTELEN);
|
||||
STREAM_GET(&node->router_id6, s, IPV6_MAX_BYTELEN);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
|
||||
STREAM_GETC(s, node->node_flag);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
|
||||
@ -1267,26 +1264,32 @@ static struct ls_attributes *ls_parse_attributes(struct stream *s)
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
|
||||
STREAM_GETF(s, attr->extended.used_bw);
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
|
||||
STREAM_GETL(s, attr->adj_sid[0].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[0].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[0].weight);
|
||||
if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2)
|
||||
STREAM_GET(attr->adj_sid[0].neighbor.sysid, s,
|
||||
ISO_SYS_ID_LEN);
|
||||
else if (attr->adv.origin == OSPFv2)
|
||||
attr->adj_sid[0].neighbor.addr.s_addr =
|
||||
stream_get_ipv4(s);
|
||||
STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
|
||||
attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr =
|
||||
stream_get_ipv4(s);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
|
||||
STREAM_GETL(s, attr->adj_sid[1].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[1].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[1].weight);
|
||||
if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2)
|
||||
STREAM_GET(attr->adj_sid[1].neighbor.sysid, s,
|
||||
ISO_SYS_ID_LEN);
|
||||
else if (attr->adv.origin == OSPFv2)
|
||||
attr->adj_sid[1].neighbor.addr.s_addr =
|
||||
stream_get_ipv4(s);
|
||||
STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
|
||||
attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr =
|
||||
stream_get_ipv4(s);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
|
||||
STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
|
||||
STREAM_GET(attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid, s,
|
||||
ISO_SYS_ID_LEN);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
|
||||
STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
|
||||
STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
|
||||
STREAM_GET(attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, s,
|
||||
ISO_SYS_ID_LEN);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
|
||||
STREAM_GETC(s, len);
|
||||
@ -1401,7 +1404,7 @@ static int ls_format_node(struct stream *s, struct ls_node *node)
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID))
|
||||
stream_put_ipv4(s, node->router_id.s_addr);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6))
|
||||
stream_put(s, &node->router6_id, IPV6_MAX_BYTELEN);
|
||||
stream_put(s, &node->router_id6, IPV6_MAX_BYTELEN);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_FLAG))
|
||||
stream_putc(s, node->node_flag);
|
||||
if (CHECK_FLAG(node->flags, LS_NODE_TYPE))
|
||||
@ -1487,26 +1490,32 @@ static int ls_format_attributes(struct stream *s, struct ls_attributes *attr)
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW))
|
||||
stream_putf(s, attr->extended.used_bw);
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
|
||||
stream_putl(s, attr->adj_sid[0].sid);
|
||||
stream_putc(s, attr->adj_sid[0].flags);
|
||||
stream_putc(s, attr->adj_sid[0].weight);
|
||||
if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2)
|
||||
stream_put(s, attr->adj_sid[0].neighbor.sysid,
|
||||
ISO_SYS_ID_LEN);
|
||||
else if (attr->adv.origin == OSPFv2)
|
||||
stream_put_ipv4(s,
|
||||
attr->adj_sid[0].neighbor.addr.s_addr);
|
||||
stream_putl(s, attr->adj_sid[ADJ_PRI_IPV4].sid);
|
||||
stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].flags);
|
||||
stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].weight);
|
||||
stream_put_ipv4(
|
||||
s, attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
|
||||
stream_putl(s, attr->adj_sid[1].sid);
|
||||
stream_putc(s, attr->adj_sid[1].flags);
|
||||
stream_putc(s, attr->adj_sid[1].weight);
|
||||
if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2)
|
||||
stream_put(s, attr->adj_sid[1].neighbor.sysid,
|
||||
ISO_SYS_ID_LEN);
|
||||
else if (attr->adv.origin == OSPFv2)
|
||||
stream_put_ipv4(s,
|
||||
attr->adj_sid[1].neighbor.addr.s_addr);
|
||||
stream_putl(s, attr->adj_sid[ADJ_BCK_IPV4].sid);
|
||||
stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].flags);
|
||||
stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].weight);
|
||||
stream_put_ipv4(
|
||||
s, attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
|
||||
stream_putl(s, attr->adj_sid[ADJ_PRI_IPV6].sid);
|
||||
stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].flags);
|
||||
stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].weight);
|
||||
stream_put(s, attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid,
|
||||
ISO_SYS_ID_LEN);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
|
||||
stream_putl(s, attr->adj_sid[ADJ_BCK_IPV6].sid);
|
||||
stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].flags);
|
||||
stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].weight);
|
||||
stream_put(s, attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid,
|
||||
ISO_SYS_ID_LEN);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
|
||||
stream_putc(s, attr->srlg_len);
|
||||
@ -1955,6 +1964,7 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty,
|
||||
struct listnode *node;
|
||||
struct ls_node *lsn;
|
||||
struct ls_edge *edge;
|
||||
struct ls_attributes *attr;
|
||||
struct ls_subnet *subnet;
|
||||
struct sbuf sbuf;
|
||||
uint32_t upper;
|
||||
@ -2019,9 +2029,15 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty,
|
||||
} else {
|
||||
sbuf_push(&sbuf, 6, "To:\t- (0.0.0.0)");
|
||||
}
|
||||
sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
|
||||
&edge->attributes->standard.local,
|
||||
&edge->attributes->standard.remote);
|
||||
attr = edge->attributes;
|
||||
if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
|
||||
sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
|
||||
&attr->standard.local,
|
||||
&attr->standard.remote);
|
||||
else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
|
||||
sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
|
||||
&attr->standard.local6,
|
||||
&attr->standard.remote6);
|
||||
}
|
||||
|
||||
sbuf_push(&sbuf, 4, "Incoming Edges: %d\n",
|
||||
@ -2034,9 +2050,15 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty,
|
||||
} else {
|
||||
sbuf_push(&sbuf, 6, "From:\t- (0.0.0.0)");
|
||||
}
|
||||
sbuf_push(&sbuf, 0, "\tRemote: %pI4\tLocal: %pI4\n",
|
||||
&edge->attributes->standard.local,
|
||||
&edge->attributes->standard.remote);
|
||||
attr = edge->attributes;
|
||||
if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)))
|
||||
sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n",
|
||||
&attr->standard.local,
|
||||
&attr->standard.remote);
|
||||
else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)))
|
||||
sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n",
|
||||
&attr->standard.local6,
|
||||
&attr->standard.remote6);
|
||||
}
|
||||
|
||||
sbuf_push(&sbuf, 4, "Subnets: %d\n", listcount(vertex->prefixes));
|
||||
@ -2071,7 +2093,7 @@ static void ls_show_vertex_json(struct ls_vertex *vertex,
|
||||
json_object_string_add(json, "router-id", buf);
|
||||
}
|
||||
if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID6)) {
|
||||
snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router6_id);
|
||||
snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router_id6);
|
||||
json_object_string_add(json, "router-id-v6", buf);
|
||||
}
|
||||
if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE))
|
||||
@ -2235,15 +2257,32 @@ static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
|
||||
sbuf_push(&sbuf, 4, "Utilized Bandwidth: %g (Bytes/s)\n",
|
||||
attr->extended.used_bw);
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) {
|
||||
sbuf_push(&sbuf, 4, "Adjacency-SID: %u", attr->adj_sid[0].sid);
|
||||
sbuf_push(&sbuf, 4, "IPv4 Adjacency-SID: %u",
|
||||
attr->adj_sid[ADJ_PRI_IPV4].sid);
|
||||
sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
|
||||
attr->adj_sid[0].flags, attr->adj_sid[0].weight);
|
||||
attr->adj_sid[ADJ_PRI_IPV4].flags,
|
||||
attr->adj_sid[ADJ_PRI_IPV4].weight);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
|
||||
sbuf_push(&sbuf, 4, "Bck. Adjacency-SID: %u",
|
||||
attr->adj_sid[1].sid);
|
||||
sbuf_push(&sbuf, 4, "IPv4 Bck. Adjacency-SID: %u",
|
||||
attr->adj_sid[ADJ_BCK_IPV4].sid);
|
||||
sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
|
||||
attr->adj_sid[1].flags, attr->adj_sid[1].weight);
|
||||
attr->adj_sid[ADJ_BCK_IPV4].flags,
|
||||
attr->adj_sid[ADJ_BCK_IPV4].weight);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
|
||||
sbuf_push(&sbuf, 4, "IPv6 Adjacency-SID: %u",
|
||||
attr->adj_sid[ADJ_PRI_IPV6].sid);
|
||||
sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
|
||||
attr->adj_sid[ADJ_PRI_IPV6].flags,
|
||||
attr->adj_sid[ADJ_PRI_IPV6].weight);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
|
||||
sbuf_push(&sbuf, 4, "IPv6 Bck. Adjacency-SID: %u",
|
||||
attr->adj_sid[ADJ_BCK_IPV6].sid);
|
||||
sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n",
|
||||
attr->adj_sid[ADJ_BCK_IPV6].flags,
|
||||
attr->adj_sid[ADJ_BCK_IPV6].weight);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
|
||||
sbuf_push(&sbuf, 4, "SRLGs: %d", attr->srlg_len);
|
||||
@ -2374,10 +2413,12 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
|
||||
jsr = json_object_new_array();
|
||||
json_object_object_add(json, "segment-routing", jsr);
|
||||
jobj = json_object_new_object();
|
||||
json_object_int_add(jobj, "adj-sid", attr->adj_sid[0].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[0].flags);
|
||||
json_object_int_add(jobj, "adj-sid",
|
||||
attr->adj_sid[ADJ_PRI_IPV4].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV4].flags);
|
||||
json_object_string_add(jobj, "flags", buf);
|
||||
json_object_int_add(jobj, "weight", attr->adj_sid[0].weight);
|
||||
json_object_int_add(jobj, "weight",
|
||||
attr->adj_sid[ADJ_PRI_IPV4].weight);
|
||||
json_object_array_add(jsr, jobj);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) {
|
||||
@ -2386,10 +2427,38 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
|
||||
json_object_object_add(json, "segment-routing", jsr);
|
||||
}
|
||||
jobj = json_object_new_object();
|
||||
json_object_int_add(jobj, "adj-sid", attr->adj_sid[1].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[1].flags);
|
||||
json_object_int_add(jobj, "adj-sid",
|
||||
attr->adj_sid[ADJ_BCK_IPV4].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV4].flags);
|
||||
json_object_string_add(jobj, "flags", buf);
|
||||
json_object_int_add(jobj, "weight", attr->adj_sid[1].weight);
|
||||
json_object_int_add(jobj, "weight",
|
||||
attr->adj_sid[ADJ_BCK_IPV4].weight);
|
||||
json_object_array_add(jsr, jobj);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) {
|
||||
jsr = json_object_new_array();
|
||||
json_object_object_add(json, "segment-routing", jsr);
|
||||
jobj = json_object_new_object();
|
||||
json_object_int_add(jobj, "adj-sid",
|
||||
attr->adj_sid[ADJ_PRI_IPV6].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV6].flags);
|
||||
json_object_string_add(jobj, "flags", buf);
|
||||
json_object_int_add(jobj, "weight",
|
||||
attr->adj_sid[ADJ_PRI_IPV6].weight);
|
||||
json_object_array_add(jsr, jobj);
|
||||
}
|
||||
if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) {
|
||||
if (!jsr) {
|
||||
jsr = json_object_new_array();
|
||||
json_object_object_add(json, "segment-routing", jsr);
|
||||
}
|
||||
jobj = json_object_new_object();
|
||||
json_object_int_add(jobj, "adj-sid",
|
||||
attr->adj_sid[ADJ_BCK_IPV6].sid);
|
||||
snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV6].flags);
|
||||
json_object_string_add(jobj, "flags", buf);
|
||||
json_object_int_add(jobj, "weight",
|
||||
attr->adj_sid[ADJ_BCK_IPV6].weight);
|
||||
json_object_array_add(jsr, jobj);
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ struct ls_node {
|
||||
struct ls_node_id adv; /* Adv. Router of this Link State */
|
||||
char name[MAX_NAME_LENGTH]; /* Name of the Node (IS-IS only) */
|
||||
struct in_addr router_id; /* IPv4 Router ID */
|
||||
struct in6_addr router6_id; /* IPv6 Router ID */
|
||||
struct in6_addr router_id6; /* IPv6 Router ID */
|
||||
uint8_t node_flag; /* IS-IS or OSPF Node flag */
|
||||
enum ls_node_type type; /* Type of Node */
|
||||
uint32_t as_number; /* Local or neighbor AS number */
|
||||
@ -166,6 +166,8 @@ struct ls_node {
|
||||
#define LS_ATTR_USE_BW 0x00400000
|
||||
#define LS_ATTR_ADJ_SID 0x01000000
|
||||
#define LS_ATTR_BCK_ADJ_SID 0x02000000
|
||||
#define LS_ATTR_ADJ_SID6 0x04000000
|
||||
#define LS_ATTR_BCK_ADJ_SID6 0x08000000
|
||||
#define LS_ATTR_SRLG 0x10000000
|
||||
|
||||
/* Link State Attributes */
|
||||
@ -200,6 +202,11 @@ struct ls_attributes {
|
||||
float rsv_bw; /* Reserved Bandwidth */
|
||||
float used_bw; /* Utilized Bandwidth */
|
||||
} extended;
|
||||
#define ADJ_PRI_IPV4 0
|
||||
#define ADJ_BCK_IPV4 1
|
||||
#define ADJ_PRI_IPV6 2
|
||||
#define ADJ_BCK_IPV6 3
|
||||
#define LS_ADJ_MAX 4
|
||||
struct ls_adjacency { /* (LAN)-Adjacency SID for OSPF */
|
||||
uint32_t sid; /* SID as MPLS label or index */
|
||||
uint8_t flags; /* Flags */
|
||||
@ -208,7 +215,7 @@ struct ls_attributes {
|
||||
struct in_addr addr; /* Neighbor @IP for OSPF */
|
||||
uint8_t sysid[ISO_SYS_ID_LEN]; /* or Sys-ID for ISIS */
|
||||
} neighbor;
|
||||
} adj_sid[2]; /* Primary & Backup (LAN)-Adj. SID */
|
||||
} adj_sid[4]; /* IPv4/IPv6 & Primary/Backup (LAN)-Adj. SID */
|
||||
uint32_t *srlgs; /* List of Shared Risk Link Group */
|
||||
uint8_t srlg_len; /* number of SRLG in the list */
|
||||
};
|
||||
@ -412,21 +419,34 @@ struct ls_subnet {
|
||||
macro_inline int vertex_cmp(const struct ls_vertex *node1,
|
||||
const struct ls_vertex *node2)
|
||||
{
|
||||
return (node1->key - node2->key);
|
||||
return numcmp(node1->key, node2->key);
|
||||
}
|
||||
DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp);
|
||||
|
||||
macro_inline int edge_cmp(const struct ls_edge *edge1,
|
||||
const struct ls_edge *edge2)
|
||||
{
|
||||
return (edge1->key - edge2->key);
|
||||
return numcmp(edge1->key, edge2->key);
|
||||
}
|
||||
DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp);
|
||||
|
||||
/*
|
||||
* Prefix comparison are done to the host part so, 10.0.0.1/24
|
||||
* and 10.0.0.2/24 are considered come different
|
||||
*/
|
||||
macro_inline int subnet_cmp(const struct ls_subnet *a,
|
||||
const struct ls_subnet *b)
|
||||
const struct ls_subnet *b)
|
||||
{
|
||||
return prefix_cmp(&a->key, &b->key);
|
||||
if (a->key.family != b->key.family)
|
||||
return numcmp(a->key.family, b->key.family);
|
||||
|
||||
if (a->key.prefixlen != b->key.prefixlen)
|
||||
return numcmp(a->key.prefixlen, b->key.prefixlen);
|
||||
|
||||
if (a->key.family == AF_INET)
|
||||
return memcmp(&a->key.u.val, &b->key.u.val, 4);
|
||||
|
||||
return memcmp(&a->key.u.val, &b->key.u.val, 16);
|
||||
}
|
||||
DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp);
|
||||
|
||||
@ -503,6 +523,16 @@ extern struct ls_vertex *ls_vertex_update(struct ls_ted *ted,
|
||||
*/
|
||||
extern void ls_vertex_clean(struct ls_ted *ted, struct ls_vertex *vertex,
|
||||
struct zclient *zclient);
|
||||
|
||||
/**
|
||||
* This function convert the ISIS ISO system ID into a 64 bits unsigned integer
|
||||
* following the architecture dependent byte order.
|
||||
*
|
||||
* @param sysid The ISO system ID
|
||||
* @return Key as 64 bits unsigned integer
|
||||
*/
|
||||
extern uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN]);
|
||||
|
||||
/**
|
||||
* Find Vertex in the Link State DB by its unique key.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user