Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ospfd: OSPF multi-instance default origination fixes (backport #17436) #17480

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions ospfd/ospf_asbr.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,38 @@ void ospf_external_info_delete(struct ospf *ospf, uint8_t type,
}
}

/*
* ospf_external_info_delete_multi_instance
*
* Delete instances of the external route information for a given route type.
* The preserve_instance parameter may be used to prevent the current instance
* from being deleted.
*/
void ospf_external_info_delete_multi_instance(struct ospf *ospf, uint8_t type, struct prefix_ipv4 p,
unsigned long preserve_instance)
{
struct route_node *rn;
struct ospf_external *ext;
struct list *ext_list;
struct listnode *node;

ext_list = ospf->external[type];
if (!ext_list)
return;

for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
if (ext->instance != preserve_instance) {
rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)&p);
if (rn) {
ospf_external_info_free(rn->info);
rn->info = NULL;
route_unlock_node(rn);
route_unlock_node(rn);
}
}
}
}

struct external_info *ospf_external_info_lookup(struct ospf *ospf, uint8_t type,
unsigned short instance,
struct prefix_ipv4 *p)
Expand All @@ -188,6 +220,44 @@ struct external_info *ospf_external_info_lookup(struct ospf *ospf, uint8_t type,
return NULL;
}

/*
* ospf_external_info_default_lookup
*
* For default information criteria, we really don't care about the
* source of the route and there only should be one.
*/
struct external_info *ospf_external_info_default_lookup(struct ospf *ospf)
{
struct ospf_external *ext;
struct external_info *ei;
struct list *ext_list;
struct listnode *node;
struct route_node *rn;
struct prefix_ipv4 p = {
.family = AF_INET,
.prefixlen = 0,
.prefix.s_addr = INADDR_ANY,
};

ext_list = ospf->external[DEFAULT_ROUTE];
if (!ext_list)
return (NULL);

for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
rn = route_node_lookup(EXTERNAL_INFO(ext), (struct prefix *)&p);
if (rn) {
route_unlock_node(rn);
if (rn->info) {
ei = rn->info;
if (ei->type != ZEBRA_ROUTE_OSPF || ei->instance != ospf->instance)
return ei;
}
}
}

return NULL;
}

struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *ospf,
struct prefix_ipv4 *p)
{
Expand Down
4 changes: 4 additions & 0 deletions ospfd/ospf_asbr.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ ospf_external_info_add(struct ospf *, uint8_t, unsigned short,
route_tag_t, uint32_t metric);
extern void ospf_external_info_delete(struct ospf *, uint8_t, unsigned short,
struct prefix_ipv4);
extern void ospf_external_info_delete_multi_instance(struct ospf *ospf, uint8_t type,
struct prefix_ipv4 p,
unsigned long preserve_instance);
#define OSPF_DELETE_ANY_INSTANCE 0xffffffff
extern struct external_info *ospf_external_info_lookup(struct ospf *, uint8_t,
unsigned short,
struct prefix_ipv4 *);
Expand Down
7 changes: 1 addition & 6 deletions ospfd/ospf_lsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -2396,15 +2396,10 @@ struct ospf_lsa *ospf_nssa_lsa_refresh(struct ospf_area *area,
static struct external_info *ospf_default_external_info(struct ospf *ospf)
{
int type;
struct prefix_ipv4 p;
struct external_info *default_ei;
int ret = 0;

p.family = AF_INET;
p.prefix.s_addr = 0;
p.prefixlen = 0;

default_ei = ospf_external_info_lookup(ospf, DEFAULT_ROUTE, 0, &p);
default_ei = ospf_external_info_default_lookup(ospf);
if (!default_ei)
return NULL;

Expand Down
3 changes: 3 additions & 0 deletions ospfd/ospf_vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -7532,6 +7532,9 @@ DEFPY (show_ip_ospf_database,
struct in_addr *adv_router_p = NULL;
json_object *json = NULL;

if (instance_id != ospf_instance)
return CMD_NOT_MY_INSTANCE;

if (uj)
json = json_object_new_object();
if (lsid_str)
Expand Down
28 changes: 18 additions & 10 deletions ospfd/ospf_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -1282,15 +1282,22 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
* originate)ZEBRA_ROUTE_MAX is used to delete the ex-info.
* Resolved this inconsistency by maintaining same route type.
*/
if ((is_default_prefix(&pgen)) && (api.type != ZEBRA_ROUTE_OSPF))
if ((is_default_prefix(&pgen)) &&
((api.type != ZEBRA_ROUTE_OSPF) || (api.instance != ospf->instance)))
rt_type = DEFAULT_ROUTE;

if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
<<<<<<< HEAD
zlog_debug(
"%s: cmd %s from client %s: vrf_id %d, p %pFX, metric %d",
__func__, zserv_command_string(cmd),
zebra_route_string(api.type), vrf_id, &api.prefix,
api.metric);
=======
zlog_debug("%s: cmd %s from client %s-%d: vrf %s(%u), p %pFX, metric %d", __func__,
zserv_command_string(cmd), zebra_route_string(api.type), api.instance,
ospf_vrf_id_to_name(vrf_id), vrf_id, &api.prefix, api.metric);
>>>>>>> 6afd56da96 (ospfd: OSPF multi-instance default origination fixes)

if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
/* XXX|HACK|TODO|FIXME:
Expand All @@ -1305,16 +1312,17 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
api.tag = ospf->dtag[rt_type];

/*
* Given zebra sends update for a prefix via ADD message, it
* should
* be considered as an implicit DEL for that prefix with other
* source
* types.
* Given zebra sends an update for a prefix via an ADD message, it
* will be considered as an impilict DELETE for that prefix for other
* types and instances other than the type and instance associated with
* the prefix.
*/
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
if (i != rt_type)
ospf_external_info_delete(ospf, i, api.instance,
p);
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++) {
unsigned long preserve_instance;

preserve_instance = (i == rt_type) ? api.instance : OSPF_DELETE_ANY_INSTANCE;
ospf_external_info_delete_multi_instance(ospf, i, p, preserve_instance);
}

ei = ospf_external_info_add(ospf, rt_type, api.instance, p,
ifindex, nexthop, api.tag,
Expand Down
3 changes: 3 additions & 0 deletions ospfd/ospf_zebra.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ extern uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *,
struct ospf_route *);
extern struct ospf_external *ospf_external_lookup(struct ospf *, uint8_t,
unsigned short);

extern struct external_info *ospf_external_info_default_lookup(struct ospf *ospf);

extern struct ospf_external *ospf_external_add(struct ospf *, uint8_t,
unsigned short);

Expand Down
19 changes: 19 additions & 0 deletions tests/topotests/ospf_multi_instance/r1/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
!
hostname r1
password zebra
log file /tmp/r1-frr.log
ip forwarding
!
interface lo
ip address 1.1.1.1/32
ip ospf area 0
!
interface r1-eth0
ip address 10.1.1.1/24
ip ospf area 0
!
!
router ospf
ospf router-id 1.1.1.1
distance 20
!
37 changes: 37 additions & 0 deletions tests/topotests/ospf_multi_instance/r2/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
!
hostname r2
password zebra
! debug ospf event
! debug ospf lsa
! debug ospf default-information
! debug ospf zebra redistribute

ip forwarding
!
interface lo1
ip address 2.2.2.1/32
ip ospf 1 area 0
no shut
!
interface lo2
ip address 2.2.2.2/32
ip ospf 2 area 0
no shut
!
interface r2-eth0
ip address 10.1.1.2/24
ip ospf 1 area 0
!
interface r2-eth1
ip address 10.1.2.2/24
ip ospf 2 area 0
!
router ospf 1
ospf router-id 2.2.2.1
distance 20
!
router ospf 2
ospf router-id 2.2.2.2
distance 20
!

19 changes: 19 additions & 0 deletions tests/topotests/ospf_multi_instance/r3/frr.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
!
hostname r3
password zebra
log file /tmp/r3-frr.log
ip forwarding
!
interface lo
ip address 3.3.3.1/32
ip ospf area 0
!
interface r3-eth0
ip address 10.1.2.3/24
ip ospf area 0
!
!
router ospf
ospf router-id 3.3.3.1
distance 20
!
Loading
Loading