bgpd: peer_af_flag_modify_vty assumes 1 flag at a time

We have a bunch of code in bgp_vty.c that was passing
to peer_af_flag_modify_vty more than 1 flag at a time.
This was causing the underlying routines to get the
flags wrong.  In order to prevent this convert all the
places where we send multiple flags down to this function
to individual flag changes.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2020-07-01 09:00:59 -04:00
parent 8f36f59ad9
commit db45f64dd2

View File

@ -4529,23 +4529,31 @@ DEFUN (neighbor_capability_orf_prefix,
"Capability to RECEIVE the ORF from this neighbor\n" "Capability to RECEIVE the ORF from this neighbor\n"
"Capability to SEND the ORF to this neighbor\n") "Capability to SEND the ORF to this neighbor\n")
{ {
int idx_peer = 1;
int idx_send_recv = 5; int idx_send_recv = 5;
uint16_t flag = 0; char *peer_str = argv[1]->arg;
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
peer = peer_and_group_lookup_vty(vty, peer_str);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (strmatch(argv[idx_send_recv]->text, "send")) if (strmatch(argv[idx_send_recv]->text, "send"))
flag = PEER_FLAG_ORF_PREFIX_SM; return peer_af_flag_set_vty(vty, peer_str, afi, safi,
else if (strmatch(argv[idx_send_recv]->text, "receive")) PEER_FLAG_ORF_PREFIX_SM);
flag = PEER_FLAG_ORF_PREFIX_RM;
else if (strmatch(argv[idx_send_recv]->text, "both"))
flag = PEER_FLAG_ORF_PREFIX_SM | PEER_FLAG_ORF_PREFIX_RM;
else {
vty_out(vty, "%% BGP invalid orf prefix-list option\n");
return CMD_WARNING_CONFIG_FAILED;
}
return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty), if (strmatch(argv[idx_send_recv]->text, "receive"))
bgp_node_safi(vty), flag); return peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_ORF_PREFIX_RM);
if (strmatch(argv[idx_send_recv]->text, "both"))
return peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_ORF_PREFIX_SM)
| peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_ORF_PREFIX_RM);
return CMD_WARNING_CONFIG_FAILED;
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(
@ -4573,24 +4581,31 @@ DEFUN (no_neighbor_capability_orf_prefix,
"Capability to RECEIVE the ORF from this neighbor\n" "Capability to RECEIVE the ORF from this neighbor\n"
"Capability to SEND the ORF to this neighbor\n") "Capability to SEND the ORF to this neighbor\n")
{ {
int idx_peer = 2;
int idx_send_recv = 6; int idx_send_recv = 6;
uint16_t flag = 0; char *peer_str = argv[2]->arg;
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
peer = peer_and_group_lookup_vty(vty, peer_str);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (strmatch(argv[idx_send_recv]->text, "send")) if (strmatch(argv[idx_send_recv]->text, "send"))
flag = PEER_FLAG_ORF_PREFIX_SM; return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
else if (strmatch(argv[idx_send_recv]->text, "receive")) PEER_FLAG_ORF_PREFIX_SM);
flag = PEER_FLAG_ORF_PREFIX_RM;
else if (strmatch(argv[idx_send_recv]->text, "both"))
flag = PEER_FLAG_ORF_PREFIX_SM | PEER_FLAG_ORF_PREFIX_RM;
else {
vty_out(vty, "%% BGP invalid orf prefix-list option\n");
return CMD_WARNING_CONFIG_FAILED;
}
return peer_af_flag_unset_vty(vty, argv[idx_peer]->arg, if (strmatch(argv[idx_send_recv]->text, "receive"))
bgp_node_afi(vty), bgp_node_safi(vty), return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
flag); PEER_FLAG_ORF_PREFIX_RM);
if (strmatch(argv[idx_send_recv]->text, "both"))
return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_ORF_PREFIX_SM)
| peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_ORF_PREFIX_RM);
return CMD_WARNING_CONFIG_FAILED;
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(
@ -4965,27 +4980,40 @@ DEFUN (neighbor_send_community_type,
"Send Standard Community attributes\n" "Send Standard Community attributes\n"
"Send Large Community attributes\n") "Send Large Community attributes\n")
{ {
int idx_peer = 1;
uint32_t flag = 0;
const char *type = argv[argc - 1]->text; const char *type = argv[argc - 1]->text;
char *peer_str = argv[1]->arg;
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
if (strmatch(type, "standard")) { peer = peer_and_group_lookup_vty(vty, peer_str);
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY); if (!peer)
} else if (strmatch(type, "extended")) { return CMD_WARNING_CONFIG_FAILED;
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
} else if (strmatch(type, "large")) { if (strmatch(type, "standard"))
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY); return peer_af_flag_set_vty(vty, peer_str, afi, safi,
} else if (strmatch(type, "both")) { PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY); if (strmatch(type, "extended"))
} else { /* if (strmatch(type, "all")) */ return peer_af_flag_set_vty(vty, peer_str, afi, safi,
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY); PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY); if (strmatch(type, "large"))
return peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY);
if (strmatch(type, "both")) {
return peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_COMMUNITY)
| peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY);
} }
return peer_af_flag_set_vty(vty, peer_str, afi, safi,
return peer_af_flag_set_vty(vty, argv[idx_peer]->arg, bgp_node_afi(vty), PEER_FLAG_SEND_COMMUNITY)
bgp_node_safi(vty), flag); | peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY)
| peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY);
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(
@ -5012,28 +5040,42 @@ DEFUN (no_neighbor_send_community_type,
"Send Standard Community attributes\n" "Send Standard Community attributes\n"
"Send Large Community attributes\n") "Send Large Community attributes\n")
{ {
int idx_peer = 2;
uint32_t flag = 0;
const char *type = argv[argc - 1]->text; const char *type = argv[argc - 1]->text;
char *peer_str = argv[2]->arg;
struct peer *peer;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
if (strmatch(type, "standard")) { peer = peer_and_group_lookup_vty(vty, peer_str);
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY); if (!peer)
} else if (strmatch(type, "extended")) { return CMD_WARNING_CONFIG_FAILED;
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
} else if (strmatch(type, "large")) { if (strmatch(type, "standard"))
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY); return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
} else if (strmatch(type, "both")) { PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY); if (strmatch(type, "extended"))
} else { /* if (strmatch(type, "all")) */ return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
SET_FLAG(flag, PEER_FLAG_SEND_COMMUNITY); PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_EXT_COMMUNITY);
SET_FLAG(flag, PEER_FLAG_SEND_LARGE_COMMUNITY); if (strmatch(type, "large"))
return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY);
if (strmatch(type, "both")) {
return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_COMMUNITY)
| peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY);
} }
return peer_af_flag_unset_vty(vty, argv[idx_peer]->arg, return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
bgp_node_afi(vty), bgp_node_safi(vty), PEER_FLAG_SEND_COMMUNITY)
flag); | peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_EXT_COMMUNITY)
| peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_SEND_LARGE_COMMUNITY);
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(
@ -5225,52 +5267,74 @@ DEFUN (neighbor_attr_unchanged,
int idx = 0; int idx = 0;
char *peer_str = argv[1]->arg; char *peer_str = argv[1]->arg;
struct peer *peer; struct peer *peer;
uint16_t flags = 0; bool aspath = false;
bool nexthop = false;
bool med = false;
afi_t afi = bgp_node_afi(vty); afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty); safi_t safi = bgp_node_safi(vty);
int ret = 0;
peer = peer_and_group_lookup_vty(vty, peer_str); peer = peer_and_group_lookup_vty(vty, peer_str);
if (!peer) if (!peer)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
if (argv_find(argv, argc, "as-path", &idx)) if (argv_find(argv, argc, "as-path", &idx))
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED); aspath = true;
idx = 0; idx = 0;
if (argv_find(argv, argc, "next-hop", &idx)) if (argv_find(argv, argc, "next-hop", &idx))
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); nexthop = true;
idx = 0; idx = 0;
if (argv_find(argv, argc, "med", &idx)) if (argv_find(argv, argc, "med", &idx))
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); med = true;
/* no flags means all of them! */ /* no flags means all of them! */
if (!flags) { if (!aspath && !nexthop && !med) {
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED); ret = peer_af_flag_set_vty(vty, peer_str, afi, safi,
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); PEER_FLAG_AS_PATH_UNCHANGED);
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); ret |= peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED);
ret |= peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED);
} else { } else {
if (!CHECK_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED) if (!aspath) {
&& peer_af_flag_check(peer, afi, safi, if (peer_af_flag_check(peer, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED)) { PEER_FLAG_AS_PATH_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, ret |= peer_af_flag_unset_vty(
PEER_FLAG_AS_PATH_UNCHANGED); vty, peer_str, afi, safi,
} PEER_FLAG_AS_PATH_UNCHANGED);
}
} else
ret |= peer_af_flag_set_vty(
vty, peer_str, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED);
if (!CHECK_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED) if (!nexthop) {
&& peer_af_flag_check(peer, afi, safi, if (peer_af_flag_check(peer, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED)) { PEER_FLAG_NEXTHOP_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, ret |= peer_af_flag_unset_vty(
PEER_FLAG_NEXTHOP_UNCHANGED); vty, peer_str, afi, safi,
} PEER_FLAG_NEXTHOP_UNCHANGED);
}
} else
ret |= peer_af_flag_set_vty(
vty, peer_str, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED);
if (!CHECK_FLAG(flags, PEER_FLAG_MED_UNCHANGED) if (!med) {
&& peer_af_flag_check(peer, afi, safi, if (peer_af_flag_check(peer, afi, safi,
PEER_FLAG_MED_UNCHANGED)) { PEER_FLAG_MED_UNCHANGED)) {
peer_af_flag_unset_vty(vty, peer_str, afi, safi, ret |= peer_af_flag_unset_vty(
PEER_FLAG_MED_UNCHANGED); vty, peer_str, afi, safi,
} PEER_FLAG_MED_UNCHANGED);
}
} else
ret |= peer_af_flag_set_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED);
} }
return peer_af_flag_set_vty(vty, peer_str, afi, safi, flags); return ret;
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(
@ -5294,27 +5358,51 @@ DEFUN (no_neighbor_attr_unchanged,
"Med attribute\n") "Med attribute\n")
{ {
int idx = 0; int idx = 0;
char *peer = argv[2]->arg; char *peer_str = argv[2]->arg;
uint16_t flags = 0; struct peer *peer;
bool aspath = false;
bool nexthop = false;
bool med = false;
afi_t afi = bgp_node_afi(vty);
safi_t safi = bgp_node_safi(vty);
int ret = 0;
peer = peer_and_group_lookup_vty(vty, peer_str);
if (!peer)
return CMD_WARNING_CONFIG_FAILED;
if (argv_find(argv, argc, "as-path", &idx)) if (argv_find(argv, argc, "as-path", &idx))
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED); aspath = true;
idx = 0; idx = 0;
if (argv_find(argv, argc, "next-hop", &idx)) if (argv_find(argv, argc, "next-hop", &idx))
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); nexthop = true;
idx = 0; idx = 0;
if (argv_find(argv, argc, "med", &idx)) if (argv_find(argv, argc, "med", &idx))
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); med = true;
if (!flags) // no flags means all of them! if (!aspath && !nexthop && !med) // no flags means all of them!
{ return peer_af_flag_unset_vty(vty, peer_str, afi, safi,
SET_FLAG(flags, PEER_FLAG_AS_PATH_UNCHANGED); PEER_FLAG_AS_PATH_UNCHANGED)
SET_FLAG(flags, PEER_FLAG_NEXTHOP_UNCHANGED); | peer_af_flag_unset_vty(vty, peer_str, afi, safi,
SET_FLAG(flags, PEER_FLAG_MED_UNCHANGED); PEER_FLAG_NEXTHOP_UNCHANGED)
} | peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED);
return peer_af_flag_unset_vty(vty, peer, bgp_node_afi(vty), if (aspath)
bgp_node_safi(vty), flags); ret |= peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_AS_PATH_UNCHANGED);
if (nexthop)
ret |= peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_NEXTHOP_UNCHANGED);
if (med)
ret |= peer_af_flag_unset_vty(vty, peer_str, afi, safi,
PEER_FLAG_MED_UNCHANGED);
return ret;
} }
ALIAS_HIDDEN( ALIAS_HIDDEN(