summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorChirag Shah <chirag@cumulusnetworks.com>2017-10-18 06:54:29 +0200
committerChirag Shah <chirag@cumulusnetworks.com>2017-10-20 23:48:13 +0200
commit9a703f8d65ec0d383eed9bb4c1bd39b528874ae5 (patch)
treef577ee3f8dd0fddb96c1f24bfc303b67f67c7845 /ospf6d
parentMerge pull request #1347 from medallia/all-routes-to-fpm (diff)
downloadfrr-9a703f8d65ec0d383eed9bb4c1bd39b528874ae5.tar.xz
frr-9a703f8d65ec0d383eed9bb4c1bd39b528874ae5.zip
ospf6d: Divide LSupdate to keep size small
Within OSPFv3 area, Disect Router LSA and Intra-prefix LSA in order to keep LSA size Small. Each LSA has unique Link State ID assigned. Intra-Area-Prefix LSA: Spread prefixes across multiple intra-area-prefix-LSAs. Ticket:CM-18069 Testing Done: Tested 92 ospf6 enabled (point-to-point) interfaces between two routers. 92 adajancy comes up with Full Neighborship. Validated 'show ipv6 ospf6 database router detail' & 'show ipv6 ospf6 database intra-prefix detail', each adv-router has two distinct LSA of such catgory. Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
Diffstat (limited to 'ospf6d')
-rw-r--r--ospf6d/ospf6_area.c1
-rw-r--r--ospf6d/ospf6_intra.c127
2 files changed, 119 insertions, 9 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index b12678624..6bbab46ad 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -234,6 +234,7 @@ struct ospf6_area *ospf6_area_create(u_int32_t area_id, struct ospf6 *o, int df)
oa->summary_prefix->scope = oa;
oa->summary_router = OSPF6_ROUTE_TABLE_CREATE(AREA, SUMMARY_ROUTERS);
oa->summary_router->scope = oa;
+ oa->router_lsa_size_limit = 1024 + 256;
/* set default options */
if (CHECK_FLAG(o->flag, OSPF6_STUB_ROUTER)) {
diff --git a/ospf6d/ospf6_intra.c b/ospf6d/ospf6_intra.c
index a2caeccb8..b5a0a9209 100644
--- a/ospf6d/ospf6_intra.c
+++ b/ospf6d/ospf6_intra.c
@@ -52,6 +52,7 @@ unsigned char conf_debug_ospf6_brouter = 0;
u_int32_t conf_debug_ospf6_brouter_specific_router_id;
u_int32_t conf_debug_ospf6_brouter_specific_area_id;
+#define MAX_LSA_PAYLOAD (1024 + 256)
/******************************/
/* RFC2740 3.4.3.1 Router-LSA */
/******************************/
@@ -214,8 +215,7 @@ int ospf6_router_lsa_originate(struct thread *thread)
ospf6_router_lsa_options_set(oa, router_lsa);
/* describe links for each interfaces */
- lsdesc = (struct ospf6_router_lsdesc
- *)((caddr_t)router_lsa
+ lsdesc = (struct ospf6_router_lsdesc *)((caddr_t)router_lsa
+ sizeof(struct ospf6_router_lsa));
for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
@@ -248,6 +248,41 @@ int ospf6_router_lsa_originate(struct thread *thread)
return 0;
}
+ /* Fill LSA Header */
+ lsa_header->age = 0;
+ lsa_header->type = htons(OSPF6_LSTYPE_ROUTER);
+ lsa_header->id = htonl(link_state_id);
+ lsa_header->adv_router = oa->ospf6->router_id;
+ lsa_header->seqnum =
+ ospf6_new_ls_seqnum(lsa_header->type,
+ lsa_header->id,
+ lsa_header->adv_router, oa->lsdb);
+ lsa_header->length =
+ htons((caddr_t)lsdesc - (caddr_t)buffer);
+
+ /* LSA checksum */
+ ospf6_lsa_checksum(lsa_header);
+
+ /* create LSA */
+ lsa = ospf6_lsa_create(lsa_header);
+
+ /* Originate */
+ ospf6_lsa_originate_area(lsa, oa);
+
+ /* 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 *)((caddr_t)lsa_header
+ + sizeof(struct ospf6_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));
+
link_state_id++;
}
@@ -861,7 +896,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
char buffer[OSPF6_MAX_LSASIZE];
struct ospf6_lsa_header *lsa_header;
- struct ospf6_lsa *old, *lsa;
+ struct ospf6_lsa *old, *lsa, *old_next = NULL;
struct ospf6_intra_prefix_lsa *intra_prefix_lsa;
struct ospf6_interface *oi;
@@ -873,6 +908,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
unsigned short prefix_num = 0;
char buf[PREFIX2STR_BUFFER];
struct ospf6_route_table *route_advertise;
+ int ls_id = 0;
oa = (struct ospf6_area *)THREAD_ARG(thread);
oa->thread_intra_prefix_lsa = NULL;
@@ -882,8 +918,22 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
oa->ospf6->router_id, oa->lsdb);
if (!IS_AREA_ENABLED(oa)) {
- if (old)
+ if (old) {
ospf6_lsa_purge(old);
+ /* find previous LSA */
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+
+ while (old_next) {
+ ospf6_lsa_purge(old_next);
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ }
+ }
return 0;
}
@@ -895,8 +945,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
/* prepare buffer */
memset(buffer, 0, sizeof(buffer));
lsa_header = (struct ospf6_lsa_header *)buffer;
- intra_prefix_lsa = (struct ospf6_intra_prefix_lsa
- *)((caddr_t)lsa_header
+ intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)((caddr_t)lsa_header
+ sizeof(struct ospf6_lsa_header));
/* Fill Intra-Area-Prefix-LSA */
@@ -945,8 +994,23 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
}
if (route_advertise->count == 0) {
- if (old)
+ if (old) {
+ ls_id = 0;
ospf6_lsa_purge(old);
+ /* find previous LSA */
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+
+ while (old_next) {
+ ospf6_lsa_purge(old_next);
+ old_next = ospf6_lsdb_lookup(
+ htons(OSPF6_LSTYPE_INTRA_PREFIX),
+ htonl(++ls_id),
+ oa->ospf6->router_id, oa->lsdb);
+ }
+ }
ospf6_route_table_delete(route_advertise);
return 0;
}
@@ -957,13 +1021,58 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
+ sizeof(struct ospf6_intra_prefix_lsa));
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 */
+ lsa_header->age = 0;
+ lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
+ lsa_header->id = htonl(ls_id++);
+ lsa_header->adv_router = oa->ospf6->router_id;
+ lsa_header->seqnum =
+ ospf6_new_ls_seqnum(lsa_header->type,
+ lsa_header->id,
+ lsa_header->adv_router,
+ oa->lsdb);
+ lsa_header->length = htons((caddr_t)op -
+ (caddr_t)lsa_header);
+
+ /* LSA checksum */
+ ospf6_lsa_checksum(lsa_header);
+
+ /* Create LSA */
+ lsa = ospf6_lsa_create(lsa_header);
+
+ /* Originate */
+ ospf6_lsa_originate_area(lsa, oa);
+
+ /* Prepare next buffer */
+ memset(buffer, 0, sizeof(buffer));
+ lsa_header = (struct ospf6_lsa_header *)buffer;
+ intra_prefix_lsa = (struct ospf6_intra_prefix_lsa *)
+ ((caddr_t)lsa_header
+ + sizeof(struct ospf6_lsa_header));
+
+ /* Fill Intra-Area-Prefix-LSA */
+ intra_prefix_lsa->ref_type = htons(OSPF6_LSTYPE_ROUTER);
+ intra_prefix_lsa->ref_id = htonl(0);
+ intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;
+
+ /* 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->prefix_length = route->prefix.prefixlen;
op->prefix_options = route->path.prefix_options;
op->prefix_metric = htons(route->path.cost);
memcpy(OSPF6_PREFIX_BODY(op), &route->prefix.u.prefix6,
OSPF6_PREFIX_SPACE(op->prefix_length));
- op = OSPF6_PREFIX_NEXT(op);
prefix_num++;
+
+ op = OSPF6_PREFIX_NEXT(op);
}
ospf6_route_table_delete(route_advertise);
@@ -980,7 +1089,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
/* Fill LSA Header */
lsa_header->age = 0;
lsa_header->type = htons(OSPF6_LSTYPE_INTRA_PREFIX);
- lsa_header->id = htonl(0);
+ lsa_header->id = htonl(ls_id++);
lsa_header->adv_router = oa->ospf6->router_id;
lsa_header->seqnum =
ospf6_new_ls_seqnum(lsa_header->type, lsa_header->id,