diff options
author | Chirag Shah <chirag@cumulusnetworks.com> | 2017-10-18 06:54:29 +0200 |
---|---|---|
committer | Chirag Shah <chirag@cumulusnetworks.com> | 2017-10-20 23:48:13 +0200 |
commit | 9a703f8d65ec0d383eed9bb4c1bd39b528874ae5 (patch) | |
tree | f577ee3f8dd0fddb96c1f24bfc303b67f67c7845 /ospf6d | |
parent | Merge pull request #1347 from medallia/all-routes-to-fpm (diff) | |
download | frr-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.c | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_intra.c | 127 |
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, |