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

gRPC northbound plugin #4082

Merged
merged 3 commits into from
May 7, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
lib: introduce a read-write lock for northbound configurations
The upcoming gRPC-based northbound plugin will run on a separate
pthread, and it will need to have access to the running configuration
global variable.  Introduce a rw-lock to control concurrent access
to the running configuration. Add the lock inside the "nb_config"
structure so that it can be used to protect candidate configurations
as well (this might be necessary depending on the threading scheme
of future northbound plugins).

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
  • Loading branch information
rwestphal committed Apr 26, 2019
commit 83981138fe8c1e0a40b8dede74eca65449dda5de
111 changes: 59 additions & 52 deletions isisd/isis_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,14 @@ DEFPY(ip_router_isis, ip_router_isis_cmd, "ip router isis WORD$tag",
}

/* check if the interface is a loopback and if so set it as passive */
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
pthread_rwlock_rdlock(&running_config->lock);
{
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
}
pthread_rwlock_unlock(&running_config->lock);

return nb_cli_apply_changes(vty, NULL);
}
Expand Down Expand Up @@ -258,10 +262,14 @@ DEFPY(ip6_router_isis, ip6_router_isis_cmd, "ipv6 router isis WORD$tag",
}

/* check if the interface is a loopback and if so set it as passive */
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
pthread_rwlock_rdlock(&running_config->lock);
{
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (ifp && if_is_loopback(ifp))
nb_cli_enqueue_change(vty, "./frr-isisd:isis/passive",
NB_OP_MODIFY, "true");
}
pthread_rwlock_unlock(&running_config->lock);

return nb_cli_apply_changes(vty, NULL);
}
Expand Down Expand Up @@ -368,20 +376,26 @@ DEFPY(no_is_type, no_is_type_cmd,
"Act as both a station router and an area router\n"
"Act as an area router only\n")
{
const char *value = NULL;
struct isis_area *area;
const char *value;

area = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
pthread_rwlock_rdlock(&running_config->lock);
{
struct isis_area *area;

area = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);

/*
* Put the is-type back to defaults:
* - level-1-2 on first area
* - level-1 for the rest
*/
if (area && listgetdata(listhead(isis->area_list)) == area)
value = "level-1-2";
else
value = NULL;
}
pthread_rwlock_unlock(&running_config->lock);

/*
* Put the is-type back to defaults:
* - level-1-2 on first area
* - level-1 for the rest
*/
if (area && listgetdata(listhead(isis->area_list)) == area)
value = "level-1-2";
else
value = NULL;
nb_cli_enqueue_change(vty, "./is-type", NB_OP_MODIFY, value);

return nb_cli_apply_changes(vty, NULL);
Expand Down Expand Up @@ -1769,50 +1783,43 @@ DEFPY(no_isis_circuit_type, no_isis_circuit_type_cmd,
"Level-1-2 adjacencies are formed\n"
"Level-2 only adjacencies are formed\n")
{
struct interface *ifp;
struct isis_circuit *circuit;
int is_type;
const char *circ_type;
const char *circ_type = NULL;

/*
* Default value depends on whether the circuit is part of an area,
* and the is-type of the area if there is one. So we need to do this
* here.
*/
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (!ifp)
goto def_val;
pthread_rwlock_rdlock(&running_config->lock);
{
struct interface *ifp;
struct isis_circuit *circuit;

circuit = circuit_scan_by_ifp(ifp);
if (!circuit)
goto def_val;
ifp = nb_running_get_entry(NULL, VTY_CURR_XPATH, false);
if (!ifp)
goto unlock;

if (circuit->state == C_STATE_UP)
is_type = circuit->area->is_type;
else
goto def_val;
circuit = circuit_scan_by_ifp(ifp);
if (!circuit || circuit->state != C_STATE_UP)
goto unlock;

switch (is_type) {
case IS_LEVEL_1:
circ_type = "level-1";
break;
case IS_LEVEL_2:
circ_type = "level-2";
break;
case IS_LEVEL_1_AND_2:
circ_type = "level-1-2";
break;
default:
return CMD_ERR_NO_MATCH;
switch (circuit->area->is_type) {
case IS_LEVEL_1:
circ_type = "level-1";
break;
case IS_LEVEL_2:
circ_type = "level-2";
break;
case IS_LEVEL_1_AND_2:
circ_type = "level-1-2";
break;
}
}
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
NB_OP_MODIFY, circ_type);

return nb_cli_apply_changes(vty, NULL);
unlock:
pthread_rwlock_unlock(&running_config->lock);

def_val:
nb_cli_enqueue_change(vty, "./frr-isisd:isis/circuit-type",
NB_OP_MODIFY, NULL);
NB_OP_MODIFY, circ_type);

return nb_cli_apply_changes(vty, NULL);
}
Expand Down
16 changes: 10 additions & 6 deletions lib/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,12 +1705,16 @@ static int vty_write_config(struct vty *vty)
vty_out(vty, "frr defaults %s\n", DFLT_NAME);
vty_out(vty, "!\n");

for (i = 0; i < vector_active(cmdvec); i++)
if ((node = vector_slot(cmdvec, i)) && node->func
&& (node->vtysh || vty->type != VTY_SHELL)) {
if ((*node->func)(vty))
vty_out(vty, "!\n");
}
pthread_rwlock_rdlock(&running_config->lock);
{
for (i = 0; i < vector_active(cmdvec); i++)
if ((node = vector_slot(cmdvec, i)) && node->func
&& (node->vtysh || vty->type != VTY_SHELL)) {
if ((*node->func)(vty))
vty_out(vty, "!\n");
}
}
pthread_rwlock_unlock(&running_config->lock);

if (vty->type == VTY_TERM) {
vty_out(vty, "end\n");
Expand Down
19 changes: 11 additions & 8 deletions lib/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,18 +187,21 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
if (yang_module_find("frr-interface")) {
struct lyd_node *if_dnode;

if_dnode = yang_dnode_get(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
ifp->name, old_vrf->name);
if (if_dnode) {
yang_dnode_change_leaf(if_dnode, vrf->name);
running_config->version++;
pthread_rwlock_wrlock(&running_config->lock);
{
if_dnode = yang_dnode_get(
running_config->dnode,
"/frr-interface:lib/interface[name='%s'][vrf='%s']/vrf",
ifp->name, old_vrf->name);
if (if_dnode) {
yang_dnode_change_leaf(if_dnode, vrf->name);
running_config->version++;
}
}
pthread_rwlock_unlock(&running_config->lock);
}
}


/* Delete interface structure. */
void if_delete_retain(struct interface *ifp)
{
Expand Down
7 changes: 6 additions & 1 deletion lib/libfrr.c
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,12 @@ static int frr_config_read_in(struct thread *t)
/*
* Update the shared candidate after reading the startup configuration.
*/
nb_config_replace(vty_shared_candidate_config, running_config, true);
pthread_rwlock_rdlock(&running_config->lock);
{
nb_config_replace(vty_shared_candidate_config, running_config,
true);
}
pthread_rwlock_unlock(&running_config->lock);

return 0;
}
Expand Down
Loading