Skip to content

Commit

Permalink
Merge pull request FRRouting#12933 from Orange-OpenSource/link_state
Browse files Browse the repository at this point in the history
lib: Update edge key in link state database
  • Loading branch information
pguibert6WIND authored Apr 20, 2023
2 parents e2bebeb + c62067c commit 7b343a9
Show file tree
Hide file tree
Showing 23 changed files with 360 additions and 277 deletions.
70 changes: 43 additions & 27 deletions isisd/isis_te.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_attributes *attr)
{
struct ls_edge *edge;
struct ls_standard *std;
uint64_t key = 0;
struct ls_edge_key key;

/* Check parameters */
if (!ted || !attr)
Expand All @@ -834,19 +834,22 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_attributes *attr)
std = &attr->standard;

/* Compute keys in function of local address (IPv4/v6) or identifier */
if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
key = ((uint64_t)ntohl(std->local.s_addr)) & 0xffffffff;
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]));
else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID))
key = ((uint64_t)std->remote_id << 32)
| (((uint64_t)std->local_id) & 0xffffffff);
else
key = 0;
if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) {
key.family = AF_INET;
IPV4_ADDR_COPY(&key.k.addr, &std->local);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) {
key.family = AF_INET6;
IPV6_ADDR_COPY(&key.k.addr6, &std->local6);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID)) {
key.family = AF_LOCAL;
key.k.link_id = (((uint64_t)std->local_id) & 0xffffffff) |
((uint64_t)std->remote_id << 32);
} else {
key.family = AF_UNSPEC;
}

/* Stop here if we don't got a valid key */
if (key == 0)
if (key.family == AF_UNSPEC)
return NULL;

/* Get corresponding Edge by key from Link State Data Base */
Expand All @@ -865,18 +868,17 @@ static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_attributes *attr)
}

if (CHECK_FLAG(edge->attributes->flags, LS_ATTR_LOCAL_ADDR))
te_debug(" |- %s Edge (%" PRIu64
") from Extended Reach. %pI4",
edge->status == NEW ? "Create" : "Found", edge->key,
&attr->standard.local);
te_debug(" |- %s Edge (%pI4) from Extended Reach. %pI4",
edge->status == NEW ? "Create" : "Found",
&edge->key.k.addr, &attr->standard.local);
else if (CHECK_FLAG(edge->attributes->flags, LS_ATTR_LOCAL_ADDR6))
te_debug(" |- %s Edge (%" PRIu64
") from Extended Reach. %pI6",
edge->status == NEW ? "Create" : "Found", edge->key,
&attr->standard.local6);
te_debug(" |- %s Edge (%pI6) from Extended Reach. %pI6",
edge->status == NEW ? "Create" : "Found",
&edge->key.k.addr6, &attr->standard.local6);
else
te_debug(" |- %s Edge (%" PRIu64 ")",
edge->status == NEW ? "Create" : "Found", edge->key);
edge->status == NEW ? "Create" : "Found",
edge->key.k.link_id);

return edge;
}
Expand Down Expand Up @@ -1118,8 +1120,21 @@ static int lsp_to_edge_cb(const uint8_t *id, uint32_t metric, bool old_metric,
}

/* Try to update remote Link from remote address or reachability ID */
te_debug(" |- Link Edge (%" PRIu64 ") to destination vertex (%s)",
edge->key, print_sys_hostname(id));
if (edge->key.family == AF_INET)
te_debug(" |- Link Edge (%pI4) to destination vertex (%s)",
&edge->key.k.addr, print_sys_hostname(id));
else if (edge->key.family == AF_INET6)
te_debug(" |- Link Edge (%pI6) to destination vertex (%s)",
&edge->key.k.addr6, print_sys_hostname(id));
else if (edge->key.family == AF_LOCAL)
te_debug(" |- Link Edge (%" PRIu64
") to destination vertex (%s)",
edge->key.k.link_id, print_sys_hostname(id));
else
te_debug(
" |- Link Edge (Unknown) to destination vertex (%s)",
print_sys_hostname(id));

dst = ls_find_edge_by_destination(args->ted, edge->attributes);
if (dst) {
/* Attach remote link if not set */
Expand Down Expand Up @@ -1909,7 +1924,7 @@ static int show_ted(struct vty *vty, struct cmd_token *argv[], int argc,
struct ls_vertex *vertex;
struct ls_edge *edge;
struct ls_subnet *subnet;
uint64_t key;
struct ls_edge_key key;
bool detail = false;
bool uj = use_json(argc, argv);
json_object *json = NULL;
Expand Down Expand Up @@ -1963,7 +1978,8 @@ static int show_ted(struct vty *vty, struct cmd_token *argv[], int argc,
return CMD_WARNING_CONFIG_FAILED;
}
/* Get the Edge from the Link State Database */
key = ((uint64_t)ntohl(ip_addr.s_addr)) & 0xffffffff;
key.family = AF_INET;
IPV4_ADDR_COPY(&key.k.addr, &ip_addr);
edge = ls_find_edge_by_key(ted, key);
if (!edge) {
vty_out(vty, "No edge found for ID %pI4\n",
Expand All @@ -1978,8 +1994,8 @@ static int show_ted(struct vty *vty, struct cmd_token *argv[], int argc,
return CMD_WARNING_CONFIG_FAILED;
}
/* Get the Edge from the Link State Database */
key = (uint64_t)ntohl(ip6_addr.s6_addr32[3])
| ((uint64_t)ntohl(ip6_addr.s6_addr32[2]) << 32);
key.family = AF_INET6;
IPV6_ADDR_COPY(&key.k.addr6, &ip6_addr);
edge = ls_find_edge_by_key(ted, key);
if (!edge) {
vty_out(vty, "No edge found for ID %pI6\n",
Expand Down
115 changes: 76 additions & 39 deletions lib/link_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,9 +674,9 @@ 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)
static struct ls_edge_key get_edge_key(struct ls_attributes *attr, bool dst)
{
uint64_t key = 0;
struct ls_edge_key key = {.family = AF_UNSPEC};
struct ls_standard *std;

if (!attr)
Expand All @@ -685,30 +685,37 @@ static uint64_t get_edge_key(struct ls_attributes *attr, bool dst)
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);
if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR)) {
/* Key is the IPv4 remote address */
key.family = AF_INET;
IPV4_ADDR_COPY(&key.k.addr, &std->remote);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6)) {
/* or the IPv6 remote address */
key.family = AF_INET6;
IPV6_ADDR_COPY(&key.k.addr6, &std->remote6);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID)) {
/* or Remote identifier if IP addr. are not defined */
key.family = AF_LOCAL;
key.k.link_id =
(((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);
if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) {
/* Key is the IPv4 local address */
key.family = AF_INET;
IPV4_ADDR_COPY(&key.k.addr, &std->local);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) {
/* or the 64 bits LSB of IPv6 local address */
key.family = AF_INET6;
IPV6_ADDR_COPY(&key.k.addr6, &std->local6);
} else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID)) {
/* or Remote identifier if IP addr. are not defined */
key.family = AF_LOCAL;
key.k.link_id =
(((uint64_t)std->local_id) & 0xffffffff) |
((uint64_t)std->remote_id << 32);
}
}

return key;
Expand All @@ -718,13 +725,13 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted,
struct ls_attributes *attributes)
{
struct ls_edge *new;
uint64_t key = 0;
struct ls_edge_key key;

if (attributes == NULL)
return NULL;

key = get_edge_key(attributes, false);
if (key == 0)
if (key.family == AF_UNSPEC)
return NULL;

/* Create Edge and add it to the TED */
Expand All @@ -742,11 +749,12 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted,
return new;
}

struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted, const uint64_t key)
struct ls_edge *ls_find_edge_by_key(struct ls_ted *ted,
const struct ls_edge_key key)
{
struct ls_edge edge = {};

if (key == 0)
if (key.family == AF_UNSPEC)
return NULL;

edge.key = key;
Expand All @@ -762,7 +770,7 @@ struct ls_edge *ls_find_edge_by_source(struct ls_ted *ted,
return NULL;

edge.key = get_edge_key(attributes, false);
if (edge.key == 0)
if (edge.key.family == AF_UNSPEC)
return NULL;

return edges_find(&ted->edges, &edge);
Expand All @@ -777,7 +785,7 @@ struct ls_edge *ls_find_edge_by_destination(struct ls_ted *ted,
return NULL;

edge.key = get_edge_key(attributes, true);
if (edge.key == 0)
if (edge.key.family == AF_UNSPEC)
return NULL;

return edges_find(&ted->edges, &edge);
Expand Down Expand Up @@ -815,7 +823,7 @@ int ls_edge_same(struct ls_edge *e1, struct ls_edge *e2)
if (!e1 && !e2)
return 1;

if (e1->key != e2->key)
if (edge_cmp(e1, e2) != 0)
return 0;

if (e1->attributes == e2->attributes)
Expand Down Expand Up @@ -2189,6 +2197,34 @@ void ls_show_vertices(struct ls_ted *ted, struct vty *vty,
}
}

static const char *edge_key_to_text(struct ls_edge_key key)
{
#define FORMAT_BUF_COUNT 4
static char buf_ring[FORMAT_BUF_COUNT][INET6_BUFSIZ];
static size_t cur_buf = 0;
char *rv;

rv = buf_ring[cur_buf];
cur_buf = (cur_buf + 1) % FORMAT_BUF_COUNT;

switch (key.family) {
case AF_INET:
snprintfrr(rv, INET6_BUFSIZ, "%pI4", &key.k.addr);
break;
case AF_INET6:
snprintfrr(rv, INET6_BUFSIZ, "%pI6", &key.k.addr6);
break;
case AF_LOCAL:
snprintfrr(rv, INET6_BUFSIZ, "%" PRIu64, key.k.link_id);
break;
default:
snprintfrr(rv, INET6_BUFSIZ, "(Unknown)");
break;
}

return rv;
}

static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
bool verbose)
{
Expand All @@ -2201,7 +2237,7 @@ static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty,
attr = edge->attributes;
sbuf_init(&sbuf, NULL, 0);

sbuf_push(&sbuf, 2, "Edge (%" PRIu64 "): ", edge->key);
sbuf_push(&sbuf, 2, "Edge (%s): ", edge_key_to_text(edge->key));
if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))
sbuf_push(&sbuf, 0, "%pI4", &attr->standard.local);
else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))
Expand Down Expand Up @@ -2360,7 +2396,7 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)

attr = edge->attributes;

json_object_int_add(json, "edge-id", edge->key);
json_object_string_add(json, "edge-id", edge_key_to_text(edge->key));
json_object_string_add(json, "status", status2txt[edge->status]);
json_object_string_add(json, "origin", origin2txt[attr->adv.origin]);
ls_node_id_to_text(attr->adv, buf, INET6_BUFSIZ);
Expand Down Expand Up @@ -2738,24 +2774,25 @@ void ls_dump_ted(struct ls_ted *ted)
for (ALL_LIST_ELEMENTS_RO(vertex->incoming_edges, lst_node,
vertex_edge)) {
zlog_debug(
" inc edge key:%" PRIu64 " attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
vertex_edge->key,
" inc edge key:%s attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
edge_key_to_text(vertex_edge->key),
&vertex_edge->attributes->adv.id.ip.addr,
&vertex_edge->attributes->standard.local,
&vertex_edge->attributes->standard.remote);
}
for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, lst_node,
vertex_edge)) {
zlog_debug(
" out edge key:%" PRIu64 " attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
vertex_edge->key,
" out edge key:%s attr key:%pI4 loc:(%pI4) rmt:(%pI4)",
edge_key_to_text(vertex_edge->key),
&vertex_edge->attributes->adv.id.ip.addr,
&vertex_edge->attributes->standard.local,
&vertex_edge->attributes->standard.remote);
}
}
frr_each (edges, &ted->edges, edge) {
zlog_debug(" Ted edge key:%" PRIu64 "src:%pI4 dst:%pI4", edge->key,
zlog_debug(" Ted edge key:%s src:%pI4 dst:%pI4",
edge_key_to_text(edge->key),
edge->source ? &edge->source->node->router_id
: &inaddr_any,
edge->destination
Expand Down
Loading

0 comments on commit 7b343a9

Please sign in to comment.