summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_intra.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_intra.c')
-rw-r--r--ospf6d/ospf6_intra.c260
1 files changed, 67 insertions, 193 deletions
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index b06796ada0..324cd7abe8 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -32,6 +32,7 @@
#include "ospf6_flood.h"
#include "ospf6d.h"
#include "ospf6_spf.h"
+#include "ospf6_tlv.h"
#include "ospf6_gr.h"
unsigned char conf_debug_ospf6_brouter = 0;
@@ -43,41 +44,20 @@ uint32_t conf_debug_ospf6_brouter_specific_area_id;
/* RFC2740 3.4.3.1 Router-LSA */
/******************************/
+/* OSPF6_LSTYPE_ROUTER */
static char *ospf6_router_lsa_get_nbr_id(struct ospf6_lsa *lsa, char *buf,
int buflen, int pos)
{
- struct ospf6_router_lsa *router_lsa;
- struct ospf6_router_lsdesc *lsdesc;
- char *start, *end;
char buf1[INET_ADDRSTRLEN], buf2[INET_ADDRSTRLEN];
+ struct ospf6_router_lsdesc *lsdesc = nth_lsdesc(lsa->header, pos);
- if (lsa) {
- router_lsa = (struct ospf6_router_lsa
- *)((char *)lsa->header
- + sizeof(struct ospf6_lsa_header));
- start = (char *)router_lsa + sizeof(struct ospf6_router_lsa);
- end = (char *)lsa->header + ntohs(lsa->header->length);
-
- lsdesc = (struct ospf6_router_lsdesc
- *)(start
- + pos * (sizeof(struct
- ospf6_router_lsdesc)));
- if ((char *)lsdesc + sizeof(struct ospf6_router_lsdesc)
- <= end) {
- if (buf && (buflen > INET_ADDRSTRLEN * 2)) {
- inet_ntop(AF_INET,
- &lsdesc->neighbor_interface_id, buf1,
- sizeof(buf1));
- inet_ntop(AF_INET, &lsdesc->neighbor_router_id,
- buf2, sizeof(buf2));
- snprintf(buf, buflen, "%s/%s", buf2, buf1);
-
- return buf;
- }
- }
- }
+ if (!lsdesc || !buf || buflen < (2 + 2 * INET_ADDRSTRLEN))
+ return NULL;
- return NULL;
+ inet_ntop(AF_INET, &lsdesc->neighbor_interface_id, buf1, sizeof(buf1));
+ inet_ntop(AF_INET, &lsdesc->neighbor_router_id, buf2, sizeof(buf2));
+ snprintf(buf, buflen, "%s/%s", buf2, buf1);
+ return buf;
}
static int ospf6_router_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
@@ -195,9 +175,7 @@ int ospf6_router_is_stub_router(struct ospf6_lsa *lsa)
struct ospf6_router_lsa *rtr_lsa;
if (lsa != NULL && OSPF6_LSA_IS_TYPE(ROUTER, lsa)) {
- rtr_lsa = (struct ospf6_router_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ rtr_lsa = lsa_after_header(lsa->header);
if (!OSPF6_OPT_ISSET(rtr_lsa->options, OSPF6_OPT_R)) {
return OSPF6_IS_STUB_ROUTER;
@@ -242,14 +220,12 @@ void ospf6_router_lsa_originate(struct event *thread)
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- router_lsa = (struct ospf6_router_lsa *)ospf6_lsa_header_end(lsa_header);
+ router_lsa = lsa_after_header(lsa_header);
ospf6_router_lsa_options_set(oa, router_lsa);
/* describe links for each interfaces */
- lsdesc = (struct ospf6_router_lsdesc
- *)((caddr_t)router_lsa
- + sizeof(struct ospf6_router_lsa));
+ lsdesc = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_ROUTER);
for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
/* Interfaces in state Down or Loopback are not described */
@@ -272,9 +248,9 @@ void ospf6_router_lsa_originate(struct event *thread)
&& ((size_t)((char *)lsdesc - buffer)
+ sizeof(struct ospf6_router_lsdesc)
> oa->router_lsa_size_limit)) {
- if ((caddr_t)lsdesc
- == (caddr_t)router_lsa
- + sizeof(struct ospf6_router_lsa)) {
+ if (lsdesc ==
+ lsdesc_start_lsa_type(lsa_header,
+ OSPF6_LSTYPE_ROUTER)) {
zlog_warn(
"Size limit setting for Router-LSA too short");
return;
@@ -303,15 +279,13 @@ void ospf6_router_lsa_originate(struct event *thread)
/* Reset Buffer to fill next Router LSA */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- router_lsa = (struct ospf6_router_lsa *)
- ospf6_lsa_header_end(lsa_header);
+ router_lsa = lsa_after_header(lsa_header);
ospf6_router_lsa_options_set(oa, router_lsa);
/* describe links for each interfaces */
- lsdesc = (struct ospf6_router_lsdesc
- *)((caddr_t)router_lsa
- + sizeof(struct ospf6_router_lsa));
+ lsdesc = lsdesc_start_lsa_type(lsa_header,
+ OSPF6_LSTYPE_ROUTER);
link_state_id++;
}
@@ -424,30 +398,13 @@ void ospf6_router_lsa_originate(struct event *thread)
static char *ospf6_network_lsa_get_ar_id(struct ospf6_lsa *lsa, char *buf,
int buflen, int pos)
{
- char *start, *end, *current;
- struct ospf6_network_lsa *network_lsa;
- struct ospf6_network_lsdesc *lsdesc;
+ struct ospf6_network_lsdesc *lsdesc = nth_lsdesc(lsa->header, pos);
- if (lsa) {
- network_lsa = (struct ospf6_network_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
-
- start = (char *)network_lsa + sizeof(struct ospf6_network_lsa);
- end = (char *)lsa->header + ntohs(lsa->header->length);
- current = start + pos * (sizeof(struct ospf6_network_lsdesc));
-
- if ((current + sizeof(struct ospf6_network_lsdesc)) <= end) {
- lsdesc = (struct ospf6_network_lsdesc *)current;
- if (buf) {
- inet_ntop(AF_INET, &lsdesc->router_id, buf,
- buflen);
- return buf;
- }
- }
- }
+ if (!lsdesc || !buf || buflen < (1 + INET_ADDRSTRLEN))
+ return NULL;
- return NULL;
+ inet_ntop(AF_INET, &lsdesc->router_id, buf, buflen);
+ return buf;
}
static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
@@ -459,9 +416,7 @@ static int ospf6_network_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
char buf[128], options[32];
json_object *json_arr = NULL;
- network_lsa =
- (struct ospf6_network_lsa *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ network_lsa = lsa_after_header(lsa->header);
ospf6_options_printbuf(network_lsa->options, options, sizeof(options));
if (use_json)
@@ -563,23 +518,19 @@ void ospf6_network_lsa_originate(struct event *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- network_lsa =
- (struct ospf6_network_lsa *)ospf6_lsa_header_end(lsa_header);
+ network_lsa = lsa_after_header(lsa_header);
/* Collect the interface's Link-LSAs to describe
network's optional capabilities */
type = htons(OSPF6_LSTYPE_LINK);
for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) {
- link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end(
- lsa->header);
+ link_lsa = lsa_after_header(lsa->header);
network_lsa->options[0] |= link_lsa->options[0];
network_lsa->options[1] |= link_lsa->options[1];
network_lsa->options[2] |= link_lsa->options[2];
}
- lsdesc = (struct ospf6_network_lsdesc
- *)((caddr_t)network_lsa
- + sizeof(struct ospf6_network_lsa));
+ lsdesc = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_NETWORK);
/* set Link Description to the router itself */
lsdesc->router_id = oi->area->ospf6->router_id;
@@ -623,52 +574,24 @@ void ospf6_network_lsa_originate(struct event *thread)
static char *ospf6_link_lsa_get_prefix_str(struct ospf6_lsa *lsa, char *buf,
int buflen, int pos)
{
- char *start, *end, *current;
- struct ospf6_link_lsa *link_lsa;
- struct in6_addr in6;
- struct ospf6_prefix *prefix;
- int cnt = 0, prefixnum;
+ struct ospf6_link_lsa *link_lsa = lsa_after_header(lsa->header);
+ struct ospf6_prefix *prefix = nth_prefix(lsa->header, pos);
+ struct in6_addr in6 = { 0 };
- if (lsa) {
- link_lsa = (struct ospf6_link_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
-
- if (pos == 0) {
- inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf,
- buflen);
- return (buf);
- }
+ if (!lsa || !prefix || !buf || buflen < (1 + INET6_ADDRSTRLEN))
+ return NULL;
- prefixnum = ntohl(link_lsa->prefix_num);
- if (pos > prefixnum)
- return NULL;
+ /* position zero is used for the lladdr in the body of the LSA */
+ if (pos == 0) {
+ inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, buflen);
+ return buf;
+ }
- start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
- end = (char *)lsa->header + ntohs(lsa->header->length);
- current = start;
-
- while (current + sizeof(struct ospf6_prefix) <= end) {
- prefix = (struct ospf6_prefix *)current;
- if (prefix->prefix_length == 0
- || current + OSPF6_PREFIX_SIZE(prefix) > end) {
- return NULL;
- }
+ memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
+ OSPF6_PREFIX_SPACE(prefix->prefix_length));
+ inet_ntop(AF_INET6, &in6, buf, buflen);
- if (cnt < (pos - 1)) {
- current += OSPF6_PREFIX_SIZE(prefix);
- cnt++;
- } else {
- memset(&in6, 0, sizeof(in6));
- memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
- OSPF6_PREFIX_SPACE(
- prefix->prefix_length));
- inet_ntop(AF_INET6, &in6, buf, buflen);
- return (buf);
- }
- }
- }
- return NULL;
+ return buf;
}
static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
@@ -684,8 +607,7 @@ static int ospf6_link_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
json_object *json_arr = NULL;
char prefix_string[133];
- link_lsa = (struct ospf6_link_lsa *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ link_lsa = lsa_after_header(lsa->header);
ospf6_options_printbuf(link_lsa->options, options, sizeof(options));
inet_ntop(AF_INET6, &link_lsa->linklocal_addr, buf, sizeof(buf));
@@ -795,7 +717,7 @@ void ospf6_link_lsa_originate(struct event *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- link_lsa = (struct ospf6_link_lsa *)ospf6_lsa_header_end(lsa_header);
+ link_lsa = lsa_after_header(lsa_header);
/* Fill Link-LSA */
link_lsa->priority = oi->priority;
@@ -804,8 +726,7 @@ void ospf6_link_lsa_originate(struct event *thread)
sizeof(struct in6_addr));
link_lsa->prefix_num = htonl(oi->route_connected->count);
- op = (struct ospf6_prefix *)((caddr_t)link_lsa
- + sizeof(struct ospf6_link_lsa));
+ op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_LINK);
/* connected prefix to advertise */
for (route = ospf6_route_head(oi->route_connected); route;
@@ -846,52 +767,22 @@ static char *ospf6_intra_prefix_lsa_get_prefix_str(struct ospf6_lsa *lsa,
char *buf, int buflen,
int pos)
{
- char *start, *end, *current;
- struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
- struct in6_addr in6;
- int prefixnum, cnt = 0;
- struct ospf6_prefix *prefix;
+ struct ospf6_prefix *prefix = nth_prefix(lsa->header, pos);
+ struct in6_addr in6 = { 0 };
char tbuf[16];
- if (lsa) {
- intra_prefix_lsa =
- (struct ospf6_intra_prefix_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ /* ensure buflen >= INET6_ADDRSTRLEN + '/128\0' */
+ if (!lsa || !prefix || !buf || buflen < (5 + INET6_ADDRSTRLEN))
+ return NULL;
- prefixnum = ntohs(intra_prefix_lsa->prefix_num);
- if ((pos + 1) > prefixnum)
- return NULL;
+ memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
+ OSPF6_PREFIX_SPACE(prefix->prefix_length));
+ inet_ntop(AF_INET6, &in6, buf, buflen);
- start = (char *)intra_prefix_lsa
- + sizeof(struct ospf6_intra_prefix_lsa);
- end = ospf6_lsa_end(lsa->header);
- current = start;
+ snprintf(tbuf, sizeof(tbuf), "/%d", prefix->prefix_length);
+ strlcat(buf, tbuf, buflen);
- while (current + sizeof(struct ospf6_prefix) <= end) {
- prefix = (struct ospf6_prefix *)current;
- if (prefix->prefix_length == 0
- || current + OSPF6_PREFIX_SIZE(prefix) > end) {
- return NULL;
- }
-
- if (cnt < pos) {
- current += OSPF6_PREFIX_SIZE(prefix);
- cnt++;
- } else {
- memset(&in6, 0, sizeof(in6));
- memcpy(&in6, OSPF6_PREFIX_BODY(prefix),
- OSPF6_PREFIX_SPACE(
- prefix->prefix_length));
- inet_ntop(AF_INET6, &in6, buf, buflen);
- snprintf(tbuf, sizeof(tbuf), "/%d",
- prefix->prefix_length);
- strlcat(buf, tbuf, buflen);
- return (buf);
- }
- }
- }
- return NULL;
+ return buf;
}
static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
@@ -908,9 +799,7 @@ static int ospf6_intra_prefix_lsa_show(struct vty *vty, struct ospf6_lsa *lsa,
json_object *json_arr = NULL;
char prefix_string[133];
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ intra_prefix_lsa = lsa_after_header(lsa->header);
prefixnum = ntohs(intra_prefix_lsa->prefix_num);
@@ -1037,8 +926,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end(
- lsa_header);
+ intra_prefix_lsa = lsa_after_header(lsa_header);
/* Fill Intra-Area-Prefix-LSA */
intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER);
@@ -1122,12 +1010,10 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
/* put prefixes to advertise */
prefix_num = 0;
- op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
- + sizeof(struct ospf6_intra_prefix_lsa));
+ op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_INTRA_PREFIX);
for (route = ospf6_route_head(route_advertise); route;
route = ospf6_route_best_next(route)) {
if (((caddr_t)op - (caddr_t)lsa_header) > MAX_LSA_PAYLOAD) {
-
intra_prefix_lsa->prefix_num = htons(prefix_num);
/* Fill LSA Header */
@@ -1153,8 +1039,7 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
/* Prepare next buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
- ospf6_lsa_header_end(lsa_header);
+ intra_prefix_lsa = lsa_after_header(lsa_header);
/* Fill Intra-Area-Prefix-LSA */
intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER);
@@ -1163,10 +1048,8 @@ void ospf6_intra_prefix_lsa_originate_stub(struct event *thread)
/* Put next set of prefixes to advertise */
prefix_num = 0;
- op = (struct ospf6_prefix
- *)((caddr_t)intra_prefix_lsa
- + sizeof(struct
- ospf6_intra_prefix_lsa));
+ op = lsdesc_start_lsa_type(lsa_header,
+ OSPF6_LSTYPE_INTRA_PREFIX);
}
op->prefix_length = route->prefix.prefixlen;
@@ -1261,8 +1144,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end(
- lsa_header);
+ intra_prefix_lsa = lsa_after_header(lsa_header);
/* Fill Intra-Area-Prefix-LSA */
intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_NETWORK);
@@ -1311,9 +1193,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread)
}
}
- link_lsa = (struct ospf6_link_lsa
- *)((caddr_t)lsa->header
- + sizeof(struct ospf6_lsa_header));
+ link_lsa = lsa_after_header(lsa->header);
prefix_num = (unsigned short)ntohl(link_lsa->prefix_num);
start = (char *)link_lsa + sizeof(struct ospf6_link_lsa);
@@ -1356,8 +1236,7 @@ void ospf6_intra_prefix_lsa_originate_transit(struct event *thread)
zlog_debug("Trailing garbage in %s", lsa->name);
}
- op = (struct ospf6_prefix *)((caddr_t)intra_prefix_lsa
- + sizeof(struct ospf6_intra_prefix_lsa));
+ op = lsdesc_start_lsa_type(lsa_header, OSPF6_LSTYPE_INTRA_PREFIX);
prefix_num = 0;
for (route = ospf6_route_head(route_advertise); route;
@@ -1658,10 +1537,7 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
}
continue;
}
- intra_prefix_lsa =
- (struct ospf6_intra_prefix_lsa *)
- ospf6_lsa_header_end(
- lsa->header);
+ intra_prefix_lsa = lsa_after_header(lsa->header);
if (intra_prefix_lsa->ref_adv_router
== oa->ospf6->router_id) {
@@ -1742,8 +1618,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
oa = OSPF6_AREA(lsa->lsdb->data);
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end(
- lsa->header);
+ intra_prefix_lsa = lsa_after_header(lsa->header);
if (intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_ROUTER) ||
intra_prefix_lsa->ref_type == htons(OSPF6_LSTYPE_NETWORK))
ospf6_linkstate_prefix(intra_prefix_lsa->ref_adv_router,
@@ -1971,8 +1846,7 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa)
oa = OSPF6_AREA(lsa->lsdb->data);
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)ospf6_lsa_header_end(
- lsa->header);
+ intra_prefix_lsa = lsa_after_header(lsa->header);
prefix_num = ntohs(intra_prefix_lsa->prefix_num);
start = (caddr_t)intra_prefix_lsa