peer->v_delayopen = from_peer->v_delayopen;
peer->v_gr_restart = from_peer->v_gr_restart;
peer->cap = from_peer->cap;
- peer->neighbor_role = from_peer->neighbor_role;
+ peer->remote_role = from_peer->remote_role;
status = peer->status;
pstatus = peer->ostatus;
last_evt = peer->last_event;
peer->cap = 0;
/* Resetting neighbor role to the default value */
- peer->neighbor_role = ROLE_UNDEFINE;
+ peer->remote_role = ROLE_UNDEFINED;
FOREACH_AFI_SAFI (afi, safi) {
/* Reset all negotiated variables */
}
uint8_t role = stream_getc(BGP_INPUT(peer));
- peer->neighbor_role = role;
+ peer->remote_role = role;
return 0;
}
static bool bgp_role_violation(struct peer *peer)
{
uint8_t local_role = peer->local_role;
- uint8_t neigh_role = peer->neighbor_role;
-
- if (local_role != ROLE_UNDEFINE && neigh_role != ROLE_UNDEFINE &&
- !((local_role == ROLE_PEER && neigh_role == ROLE_PEER) ||
- (local_role == ROLE_PROVIDER && neigh_role == ROLE_CUSTOMER) ||
- (local_role == ROLE_CUSTOMER && neigh_role == ROLE_PROVIDER) ||
- (local_role == ROLE_RS_SERVER && neigh_role == ROLE_RS_CLIENT) ||
- (local_role == ROLE_RS_CLIENT && neigh_role == ROLE_RS_SERVER))) {
+ uint8_t remote_role = peer->remote_role;
+
+ if (local_role != ROLE_UNDEFINED && remote_role != ROLE_UNDEFINED &&
+ !((local_role == ROLE_PEER && remote_role == ROLE_PEER) ||
+ (local_role == ROLE_PROVIDER && remote_role == ROLE_CUSTOMER) ||
+ (local_role == ROLE_CUSTOMER && remote_role == ROLE_PROVIDER) ||
+ (local_role == ROLE_RS_SERVER && remote_role == ROLE_RS_CLIENT) ||
+ (local_role == ROLE_RS_CLIENT &&
+ remote_role == ROLE_RS_SERVER))) {
bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_ROLE_MISMATCH);
return true;
}
- if (neigh_role == ROLE_UNDEFINE &&
+ if (remote_role == ROLE_UNDEFINED &&
CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_MODE)) {
const char *err_msg =
"Strict mode. Please set the role on your side.";
stream_putc(s, CAPABILITY_CODE_EXT_MESSAGE_LEN);
/* Role*/
- if (peer->local_role != ROLE_UNDEFINE) {
+ if (peer->local_role != ROLE_UNDEFINED) {
SET_FLAG(peer->cap, PEER_CAP_ROLE_ADV);
stream_putc(s, BGP_OPEN_OPT_CAP);
stream_putc(s, CAPABILITY_CODE_ROLE_LEN + 2);
str = "Invalid role name";
break;
case BGP_ERR_INVALID_INTERNAL_ROLE:
- str = "Extrenal roles can be set only on eBGP session";
+ str = "External roles can be set only on eBGP session";
break;
}
if (str) {
return ROLE_RS_SERVER;
if (strncmp(role_str, "rs-client", 4) == 0)
return ROLE_RS_CLIENT;
- return ROLE_UNDEFINE;
+ return ROLE_UNDEFINED;
}
static int peer_role_set_vty(struct vty *vty, const char *ip_str,
- const char *role_str, int strict_mode)
+ const char *role_str, bool strict_mode)
{
struct peer *peer;
return CMD_WARNING_CONFIG_FAILED;
uint8_t role = get_role_by_name(role_str);
- if (role == ROLE_UNDEFINE)
+ if (role == ROLE_UNDEFINED)
return bgp_vty_return(vty, BGP_ERR_INVALID_ROLE_NAME);
return bgp_vty_return(vty, peer_role_set(peer, role, strict_mode));
}
return bgp_vty_return(vty, peer_role_unset(peer));
}
-DEFUN(neighbor_role,
+DEFPY(neighbor_role,
neighbor_role_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer>",
NEIGHBOR_STR
int idx_role = 3;
return peer_role_set_vty(vty, argv[idx_peer]->arg, argv[idx_role]->arg,
- 0);
+ false);
}
-DEFUN(neighbor_role_strict,
+DEFPY(neighbor_role_strict,
neighbor_role_strict_cmd,
"neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer> strict-mode",
NEIGHBOR_STR
int idx_role = 3;
return peer_role_set_vty(vty, argv[idx_peer]->arg, argv[idx_role]->arg,
- 1);
+ true);
}
-DEFUN(no_neighbor_role,
+DEFPY(no_neighbor_role,
no_neighbor_role_cmd,
"no neighbor <A.B.C.D|X:X::X:X|WORD> local-role <provider|rs-server|rs-client|customer|peer> [strict-mode]",
NO_STR
NEIGHBOR_STR
NEIGHBOR_ADDR_STR2
- "Unset session role\n"
+ "Set session role\n"
ROLE_STR
- "Was used additional restriction on peer\n")
+ "Use additional restriction on peer\n")
{
int idx_peer = 2;
/* Roles */
if (use_json) {
json_object_string_add(json_neigh, "localRole",
- get_name_by_role(p->local_role));
- json_object_string_add(json_neigh, "neighRole",
- get_name_by_role(p->neighbor_role));
+ bgp_get_name_by_role(p->local_role));
+ json_object_string_add(json_neigh, "remoteRole",
+ bgp_get_name_by_role(p->remote_role));
} else {
vty_out(vty, " Local Role: %s\n",
- get_name_by_role(p->local_role));
- vty_out(vty, " Neighbor Role: %s\n",
- get_name_by_role(p->neighbor_role));
+ bgp_get_name_by_role(p->local_role));
+ vty_out(vty, " Remote Role: %s\n",
+ bgp_get_name_by_role(p->remote_role));
}
}
/* role */
- if (peer->local_role != ROLE_UNDEFINE) {
+ if (peer->local_role != ROLE_UNDEFINED) {
vty_out(vty, " neighbor %s local-role %s%s\n", addr,
- get_name_by_role(peer->local_role),
+ bgp_get_name_by_role(peer->local_role),
CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_MODE)
? " strict-mode"
: "");
peer->cur_event = peer->last_event = peer->last_major_event = 0;
peer->bgp = bgp_lock(bgp);
peer = peer_lock(peer); /* initial reference */
- peer->local_role = ROLE_UNDEFINE;
- peer->neighbor_role = ROLE_UNDEFINE;
+ peer->local_role = ROLE_UNDEFINED;
+ peer->remote_role = ROLE_UNDEFINED;
peer->password = NULL;
peer->max_packet_size = BGP_STANDARD_MESSAGE_MAX_PACKET_SIZE;
return 0;
}
-const char *get_name_by_role(uint8_t role)
+const char *bgp_get_name_by_role(uint8_t role)
{
static const char *const bgp_role_names[] = {
"provider", "rs-server", "rs-client", "customer", "peer"};
- if (role == ROLE_UNDEFINE)
- return "undefine";
+ if (role == ROLE_UNDEFINED)
+ return "undefined";
if (role <= 5)
return bgp_role_names[role];
return "unknown";
{PEER_FLAG_UPDATE_SOURCE, 0, peer_change_none},
{PEER_FLAG_DISABLE_LINK_BW_ENCODING_IEEE, 0, peer_change_none},
{PEER_FLAG_EXTENDED_OPT_PARAMS, 0, peer_change_reset},
+ {PEER_FLAG_STRICT_MODE, 0, peer_change_reset},
{0, 0, 0}};
static const struct peer_flag_action peer_af_flag_action_list[] = {
}
/* Set Open Policy Role and check its correctness */
-int peer_role_set(struct peer *peer, uint8_t role, int strict_mode)
+int peer_role_set(struct peer *peer, uint8_t role, bool strict_mode)
{
if (peer->local_role == role) {
if (CHECK_FLAG(peer->flags, PEER_FLAG_STRICT_MODE) &&
SET_FLAG(peer->flags, PEER_FLAG_STRICT_MODE);
/* Restart session to throw Role Mismatch Notification
*/
- if (peer->neighbor_role == ROLE_UNDEFINE)
+ if (peer->remote_role == ROLE_UNDEFINED)
bgp_session_reset(peer);
}
} else {
int peer_role_unset(struct peer *peer)
{
- return peer_role_set(peer, ROLE_UNDEFINE, 0);
+ return peer_role_set(peer, ROLE_UNDEFINED, 0);
}
/* Neighbor description. */
/* Roles in bgp session */
uint8_t local_role;
- uint8_t neighbor_role;
+ uint8_t remote_role;
#define ROLE_PROVIDER 0
#define ROLE_RS_SERVER 1
#define ROLE_RS_CLIENT 2
#define ROLE_CUSTOMER 3
#define ROLE_PEER 4
-#define ROLE_UNDEFINE 255
+#define ROLE_UNDEFINED 255
#define ROLE_NAME_MAX_LEN 20
extern int peer_ebgp_multihop_unset(struct peer *);
extern int is_ebgp_multihop_configured(struct peer *peer);
-extern int peer_role_set(struct peer *peer, uint8_t role, int strict_mode);
+extern int peer_role_set(struct peer *peer, uint8_t role, bool strict_mode);
extern int peer_role_unset(struct peer *peer);
extern void peer_description_set(struct peer *, const char *);
extern void peer_tx_shutdown_message_unset(struct peer *);
extern void bgp_route_map_update_timer(struct thread *thread);
-extern const char *get_name_by_role(uint8_t role);
+extern const char *bgp_get_name_by_role(uint8_t role);
extern void bgp_route_map_terminate(void);
To enable its mechanics, you must set your local role to reflect your type of
peering relationship with your neighbor. Possible values of ``LOCAL-ROLE`` are:
-<provider|rs-server|rs-client|customer|peer>.
+
+- provider
+- rs-server
+- rs-client
+- customer
+- peer
The local Role value is negotiated with the new BGP Role capability with a
built-in check of the corresponding value. In case of mismatch the new OPEN
Role: advertised and received
If strict-mode is set BGP session won't become established until BGP neighbor
-set local Role on its side. This configuratoin parameter is defined in
+set local Role on its side. This configuration parameter is defined in
:rfc:`9234` and used to enforce corresponding configuration at your
-conter-part side. Default value - disabled.
+counter-part side. Default value - disabled.
Routes that sent from provider, rs-server, or peer local-role (or if received
by customer, rs-clinet, or peer local-role) will be marked with a new
local-role is provider or rs-server. Routes with this attribute can be
received only if your local-role is customer or rs-client.
-In case of peer-peer relaitonship routes can be received only if
+In case of peer-peer relationship routes can be received only if
OTC value is equal to your neighbor AS number.
All these rules with OTC help to detect and mitigate route leaks and
This command set your local-role to ``LOCAL-ROLE``:
<provider|rs-server|rs-client|customer|peer>.
- This role help to detect and prevent route leaks.
+ This role helps to detect and prevent route leaks.
If ``strict-mode`` is set, your neighbor must send you Capability with the
value of his role (by setting local-role on his side). Otherwise, a Role
! Correct role pair
neighbor 192.168.2.2 remote-as 64502
neighbor 192.168.2.2 local-role provider
+ neighbor 192.168.2.2 timers 3 10
! Incorrect role pair
neighbor 192.168.3.2 remote-as 64503
neighbor 192.168.3.2 local-role provider
+ neighbor 192.168.3.2 timers 3 10
! Missed neighbor role
neighbor 192.168.4.2 remote-as 64504
neighbor 192.168.4.2 local-role provider
+ neighbor 192.168.4.2 timers 3 10
! Missed neighbor role with strict-mode
neighbor 192.168.5.2 remote-as 64505
neighbor 192.168.5.2 local-role provider strict-mode
+ neighbor 192.168.5.2 timers 3 10
bgp router-id 192.168.2.2
neighbor 192.168.2.1 remote-as 64501
neighbor 192.168.2.1 local-role customer
+ neighbor 192.168.2.1 timers 3 10
router bgp 64503
neighbor 192.168.3.1 remote-as 64501
neighbor 192.168.3.1 local-role peer
+ neighbor 192.168.3.1 timers 3 10
router bgp 64504
neighbor 192.168.4.1 remote-as 64501
+ neighbor 192.168.4.1 timers 3 10
router bgp 64505
neighbor 192.168.5.1 remote-as 64501
+ neighbor 192.168.5.1 timers 3 10
tgen.gears["r1"].vtysh_cmd(f"show bgp neighbors {neighbor_ip} json")
)[neighbor_ip]
assert neighbor_status["localRole"] == "provider"
- assert neighbor_status["neighRole"] == "customer"
+ assert neighbor_status["remoteRole"] == "customer"
assert neighbor_status["bgpState"] == "Established"
assert (
neighbor_status["neighborCapabilities"].get("role") == "advertisedAndReceived"
def test_single_role_advertising(tgen):
- # provider-undefine pair; we set role
+ # provider-undefined pair; we set role
neighbor_ip = "192.168.4.2"
neighbor_status = json.loads(
tgen.gears["r1"].vtysh_cmd(f"show bgp neighbors {neighbor_ip} json")
)[neighbor_ip]
assert neighbor_status["localRole"] == "provider"
- assert neighbor_status["neighRole"] == "undefine"
+ assert neighbor_status["remoteRole"] == "undefined"
assert neighbor_status["bgpState"] == "Established"
assert neighbor_status["neighborCapabilities"].get("role") == "advertised"
def test_single_role_receiving(tgen):
- # provider-undefine pair; we receive role
+ # provider-undefined pair; we receive role
neighbor_ip = "192.168.4.1"
neighbor_status = json.loads(
tgen.gears["r4"].vtysh_cmd(f"show bgp neighbors {neighbor_ip} json")
)[neighbor_ip]
- assert neighbor_status["localRole"] == "undefine"
- assert neighbor_status["neighRole"] == "provider"
+ assert neighbor_status["localRole"] == "undefined"
+ assert neighbor_status["remoteRole"] == "provider"
assert neighbor_status["bgpState"] == "Established"
assert neighbor_status["neighborCapabilities"].get("role") == "received"
def test_role_strict_mode(tgen):
- # provider-undefine pair bur strict-mode was set
+ # provider-undefined pair with strict-mode
neighbor_ip = "192.168.5.2"
neighbor_status = json.loads(
tgen.gears["r1"].vtysh_cmd(f"show bgp neighbors {neighbor_ip} json")
BGP_CONVERGENCE = verify_bgp_convergence_from_running_config(tgen)
assert BGP_CONVERGENCE, f"setup_module :Failed \n Error: {BGP_CONVERGENCE}"
# Todo: What is the indented way to wait for convergence without json?!
- time.sleep(3)
+ time.sleep(5)
yield tgen
tgen.stop_topology()