Skip to content

Commit

Permalink
Merge pull request #8622 from volta-networks/fix_ospf6_max_if_addr
Browse files Browse the repository at this point in the history
ospf6d: Limit the number of interface addresses being supported in ospfv3
  • Loading branch information
riw777 authored May 12, 2021
2 parents 449e54f + 9160389 commit 6158f83
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 7 deletions.
10 changes: 10 additions & 0 deletions doc/user/ospf6d.rst
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,13 @@ Larger example with policy and various options set:
ipv6 access-class access6
exec-timeout 0 0
!
Configuration Limits
====================

Ospf6d currently supports 100 interfaces addresses if MTU is set to
default value, and 200 interface addresses if MTU is set to jumbo
packet size or larger.


13 changes: 13 additions & 0 deletions ospf6d/ospf6_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
struct connected *c;
struct listnode *node, *nnode;
struct in6_addr nh_addr;
int count = 0, max_addr_count;

oi = (struct ospf6_interface *)ifp->info;
if (oi == NULL)
Expand All @@ -423,10 +424,22 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
/* update "route to advertise" interface route table */
ospf6_route_remove_all(oi->route_connected);

if (oi->ifmtu >= OSPF6_JUMBO_MTU)
max_addr_count = OSPF6_MAX_IF_ADDRS_JUMBO;
else
max_addr_count = OSPF6_MAX_IF_ADDRS;

for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
if (c->address->family != AF_INET6)
continue;

/* number of interface addresses supported is based on MTU
* size of OSPFv3 packet
*/
count++;
if (count >= max_addr_count)
break;

CONTINUE_IF_ADDRESS_LINKLOCAL(IS_OSPF6_DEBUG_INTERFACE,
c->address);
CONTINUE_IF_ADDRESS_UNSPECIFIED(IS_OSPF6_DEBUG_INTERFACE,
Expand Down
1 change: 1 addition & 0 deletions ospf6d/ospf6_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ extern void ospf6_interface_disable(struct ospf6_interface *);
extern void ospf6_interface_if_add(struct interface *);
extern void ospf6_interface_state_update(struct interface *);
extern void ospf6_interface_connected_route_update(struct interface *);
extern void ospf6_interface_connected_route_add(struct connected *);

/* interface event */
extern int interface_up(struct thread *);
Expand Down
32 changes: 26 additions & 6 deletions ospf6d/ospf6_intra.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,7 @@ int ospf6_link_lsa_originate(struct thread *thread)
struct ospf6_link_lsa *link_lsa;
struct ospf6_route *route;
struct ospf6_prefix *op;
int count, max_addr_count;

oi = (struct ospf6_interface *)THREAD_ARG(thread);
oi->thread_link_lsa = NULL;
Expand Down Expand Up @@ -800,14 +801,20 @@ int ospf6_link_lsa_originate(struct thread *thread)
memcpy(link_lsa->options, oi->area->options, 3);
memcpy(&link_lsa->linklocal_addr, oi->linklocal_addr,
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));

/* connected prefix to advertise */
for (route = ospf6_route_head(oi->route_connected); route;
route = ospf6_route_next(route)) {
/* connected prefix to advertise, number of interface addresses
* supported is based on MTU size of OSPFv3 packets
*/
if (oi->ifmtu >= OSPF6_JUMBO_MTU)
max_addr_count = OSPF6_MAX_IF_ADDRS_JUMBO;
else
max_addr_count = OSPF6_MAX_IF_ADDRS;
for (route = ospf6_route_head(oi->route_connected), count = 0;
route && count < max_addr_count;
route = ospf6_route_next(route), count++) {
op->prefix_length = route->prefix.prefixlen;
op->prefix_options = route->path.prefix_options;
op->prefix_metric = htons(0);
Expand All @@ -816,6 +823,8 @@ int ospf6_link_lsa_originate(struct thread *thread)
op = OSPF6_PREFIX_NEXT(op);
}

link_lsa->prefix_num = htonl(count);

/* Fill LSA Header */
lsa_header->age = 0;
lsa_header->type = htons(OSPF6_LSTYPE_LINK);
Expand Down Expand Up @@ -995,6 +1004,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
unsigned short prefix_num = 0;
struct ospf6_route_table *route_advertise;
int ls_id = 0;
int count, max_addr_count;

oa = (struct ospf6_area *)THREAD_ARG(thread);
oa->thread_intra_prefix_lsa = NULL;
Expand Down Expand Up @@ -1040,6 +1050,8 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
intra_prefix_lsa->ref_adv_router = oa->ospf6->router_id;

route_advertise = ospf6_route_table_create(0, 0);
route_advertise->hook_add = NULL;
route_advertise->hook_remove = NULL;

for (ALL_LIST_ELEMENTS_RO(oa->if_list, i, oi)) {
if (oi->state == OSPF6_INTERFACE_DOWN) {
Expand Down Expand Up @@ -1068,8 +1080,14 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
zlog_debug(" Interface %s:", oi->interface->name);

/* connected prefix to advertise */
for (route = ospf6_route_head(oi->route_connected); route;
route = ospf6_route_best_next(route)) {
if (oi->ifmtu >= OSPF6_JUMBO_MTU)
max_addr_count = OSPF6_MAX_IF_ADDRS_JUMBO;
else
max_addr_count = OSPF6_MAX_IF_ADDRS;

for (route = ospf6_route_head(oi->route_connected), count = 0;
route && count < max_addr_count;
route = ospf6_route_best_next(route), count++) {
if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
zlog_debug(" include %pFX", &route->prefix);
ospf6_route_add(ospf6_route_copy(route),
Expand Down Expand Up @@ -1284,6 +1302,8 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)

/* connected prefix to advertise */
route_advertise = ospf6_route_table_create(0, 0);
route_advertise->hook_add = NULL;
route_advertise->hook_remove = NULL;

type = ntohs(OSPF6_LSTYPE_LINK);
for (ALL_LSDB_TYPED(oi->lsdb, type, lsa)) {
Expand Down
18 changes: 18 additions & 0 deletions ospf6d/ospf6_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,7 @@ DEFUN (ospf6_interface_area,
struct ospf6_interface *oi;
struct interface *ifp;
vrf_id_t vrf_id = VRF_DEFAULT;
int ipv6_count = 0;

if (ospf6->vrf_id != VRF_UNKNOWN)
vrf_id = ospf6->vrf_id;
Expand All @@ -865,6 +866,23 @@ DEFUN (ospf6_interface_area,
return CMD_SUCCESS;
}

/* if more than OSPF6_MAX_IF_ADDRS are configured on this interface
* then don't allow ospfv3 to be configured
*/
ipv6_count = connected_count_by_family(ifp, AF_INET6);
if (oi->ifmtu == OSPF6_DEFAULT_MTU && ipv6_count > OSPF6_MAX_IF_ADDRS) {
vty_out(vty,
"can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
ifp->name, OSPF6_MAX_IF_ADDRS, ipv6_count);
return CMD_WARNING_CONFIG_FAILED;
} else if (oi->ifmtu >= OSPF6_JUMBO_MTU
&& ipv6_count > OSPF6_MAX_IF_ADDRS_JUMBO) {
vty_out(vty,
"can not configure OSPFv3 on if %s, must have less than %d interface addresses but has %d addresses\n",
ifp->name, OSPF6_MAX_IF_ADDRS_JUMBO, ipv6_count);
return CMD_WARNING_CONFIG_FAILED;
}

/* parse Area-ID */
OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);

Expand Down
4 changes: 4 additions & 0 deletions ospf6d/ospf6_top.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ DECLARE_QOBJ_TYPE(ospf6);
#define OSPF6_DISABLED 0x01
#define OSPF6_STUB_ROUTER 0x02
#define OSPF6_FLAG_ASBR 0x04
#define OSPF6_MAX_IF_ADDRS 100
#define OSPF6_MAX_IF_ADDRS_JUMBO 200
#define OSPF6_DEFAULT_MTU 1500
#define OSPF6_JUMBO_MTU 9000

/* global pointer for OSPF top data structure */
extern struct ospf6 *ospf6;
Expand Down
23 changes: 22 additions & 1 deletion ospf6d/ospf6_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,38 @@ void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id)
static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
{
struct connected *c;
struct ospf6_interface *oi;
int ipv6_count = 0;

c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
zclient->ibuf, vrf_id);
if (c == NULL)
return 0;

oi = (struct ospf6_interface *)c->ifp->info;
if (oi == NULL)
oi = ospf6_interface_create(c->ifp);
assert(oi);

if (IS_OSPF6_DEBUG_ZEBRA(RECV))
zlog_debug("Zebra Interface address add: %s %5s %pFX",
c->ifp->name, prefix_family_str(c->address),
c->address);

ipv6_count = connected_count_by_family(c->ifp, AF_INET6);
if (oi->ifmtu == OSPF6_DEFAULT_MTU && ipv6_count > OSPF6_MAX_IF_ADDRS) {
zlog_warn(
"Zebra Interface : %s has too many interface addresses %d only support %d, increase MTU",
c->ifp->name, ipv6_count, OSPF6_MAX_IF_ADDRS);
return 0;
} else if (oi->ifmtu >= OSPF6_JUMBO_MTU
&& ipv6_count > OSPF6_MAX_IF_ADDRS_JUMBO) {
zlog_warn(
"Zebra Interface : %s has too many interface addresses %d only support %d",
c->ifp->name, ipv6_count, OSPF6_MAX_IF_ADDRS_JUMBO);
return 0;
}

if (c->address->family == AF_INET6) {
ospf6_interface_state_update(c->ifp);
ospf6_interface_connected_route_update(c->ifp);
Expand Down Expand Up @@ -303,7 +324,7 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
struct prefix *dest;

if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug("Send %s route: %pFX",
zlog_debug("Zebra Send %s route: %pFX",
(type == REM ? "remove" : "add"), &request->prefix);

if (zclient->sock < 0) {
Expand Down

0 comments on commit 6158f83

Please sign in to comment.