Skip to content

Commit 411200e

Browse files
committed
Issue #21: Implementation of local-as command
Change-Id: Id6a0f974276ee66bdd6251dab5e7f2055b39f4f3
1 parent ef7fa13 commit 411200e

3 files changed

Lines changed: 173 additions & 20 deletions

File tree

vtysh/bgp_vty.c

Lines changed: 157 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2709,6 +2709,30 @@ is_ibgp_peer(const struct ovsrec_bgp_neighbor *ovs_bgp_neighbor,
27092709
return false;
27102710
}
27112711

2712+
void
2713+
remove_parameters_invalid_for_ibgp_peer(const struct ovsrec_bgp_neighbor *ovs_bgp_neighbor)
2714+
{
2715+
if (ovs_bgp_neighbor->n_remove_private_as) {
2716+
ovsrec_bgp_neighbor_set_remove_private_as(ovs_bgp_neighbor, NULL, 0);
2717+
}
2718+
2719+
if (ovs_bgp_neighbor->n_local_as) {
2720+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, NULL, 0);
2721+
}
2722+
}
2723+
2724+
bool
2725+
is_member_of_peer_group(const struct ovsrec_bgp_neighbor *ovs_bgp_neighbor,
2726+
const struct ovsrec_bgp_neighbor *ovs_peer_grp)
2727+
{
2728+
if (object_is_bgp_neighbor(ovs_bgp_neighbor)) {
2729+
if (ovs_bgp_neighbor->bgp_peer_group == ovs_peer_grp) {
2730+
return true;
2731+
}
2732+
}
2733+
return false;
2734+
}
2735+
27122736
/*
27132737
* Assigns a remote-as to an *EXISTING* peer group OR
27142738
* creates a NEW peer with remote-as if none exists or
@@ -2787,24 +2811,21 @@ cli_neighbor_remote_as_cmd_execute(char *vrf_name, struct vty *vty,
27872811

27882812
ovsrec_bgp_neighbor_set_remote_as(ovs_bgp_neighbor, &remote_as, 1);
27892813

2790-
if (ovs_bgp_neighbor->remove_private_as && is_ibgp_peer(ovs_bgp_neighbor, asn))
2791-
{
2792-
ovsrec_bgp_neighbor_set_remove_private_as(ovs_bgp_neighbor, NULL, 0);
2814+
if (is_ibgp_peer(ovs_bgp_neighbor, asn)) {
2815+
remove_parameters_invalid_for_ibgp_peer(ovs_bgp_neighbor);
27932816
}
2817+
27942818
/*
27952819
* If we are a peer group whose remote-as has just been set or changed,
27962820
* update the remote-as of all the peers bound to this peer group.
27972821
*/
27982822
if (update_all_peers) {
27992823
OVSREC_BGP_NEIGHBOR_FOR_EACH(ovs_bgp_neighbor, idl) {
2800-
if (object_is_bgp_neighbor(ovs_bgp_neighbor)) {
2801-
if (ovs_bgp_neighbor->bgp_peer_group == ovs_peer_grp) {
2802-
ovsrec_bgp_neighbor_set_remote_as(ovs_bgp_neighbor,
2803-
&remote_as, 1);
2804-
if (ovs_bgp_neighbor->remove_private_as && is_ibgp_peer(ovs_bgp_neighbor, asn))
2805-
{
2806-
ovsrec_bgp_neighbor_set_remove_private_as(ovs_bgp_neighbor, NULL, 0);
2807-
}
2824+
if (is_member_of_peer_group(ovs_bgp_neighbor, ovs_peer_grp)) {
2825+
ovsrec_bgp_neighbor_set_remote_as(ovs_bgp_neighbor,
2826+
&remote_as, 1);
2827+
if (is_ibgp_peer(ovs_bgp_neighbor, asn)) {
2828+
remove_parameters_invalid_for_ibgp_peer(ovs_bgp_neighbor);
28082829
}
28092830
}
28102831
}
@@ -3237,6 +3258,114 @@ DEFUN(no_neighbor_peer_group_remote_as,
32373258
return CMD_SUCCESS;
32383259
}
32393260

3261+
static int
3262+
cli_neighbor_local_as_cmd_execute(char *vrf_name, const char *argv[])
3263+
{
3264+
const char *peer_str = argv[0];
3265+
int64_t local_as = strtoll(argv[1], NULL, 10);
3266+
const struct ovsrec_bgp_router *bgp_router_context;
3267+
const struct ovsrec_vrf *vrf_row;
3268+
const struct ovsrec_bgp_neighbor *ovs_bgp_neighbor, *ovs_peer_grp;
3269+
struct ovsdb_idl_txn *txn;
3270+
int64_t asn = (int64_t)vty->index;
3271+
3272+
START_DB_TXN(txn);
3273+
3274+
vrf_row = get_ovsrec_vrf_with_name(vrf_name);
3275+
if (!vrf_row) {
3276+
ERRONEOUS_DB_TXN(txn, BGP_ERR_NO_VRF_FOUND);
3277+
}
3278+
3279+
bgp_router_context = get_ovsrec_bgp_router_with_asn(vrf_row, asn);
3280+
if (!bgp_router_context) {
3281+
ERRONEOUS_DB_TXN(txn, BGP_ERR_ROUTER_IS_NOT_CONFIGURED);
3282+
}
3283+
3284+
ovs_bgp_neighbor =
3285+
get_bgp_peer_group_with_bgp_router_and_name(bgp_router_context, peer_str);
3286+
if (!ovs_bgp_neighbor) {
3287+
ABORT_DB_TXN(txn, BGP_ERR_NEIGHBOR_IS_NOT_CONFIGURED);
3288+
}
3289+
3290+
if(ovs_bgp_neighbor->bgp_peer_group) {
3291+
ABORT_DB_TXN(txn, BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER);
3292+
}
3293+
3294+
if (is_ibgp_peer(ovs_bgp_neighbor, asn)) {
3295+
ABORT_DB_TXN(txn, BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP);
3296+
}
3297+
3298+
if (local_as == asn) {
3299+
ABORT_DB_TXN(txn, BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS);
3300+
}
3301+
3302+
if (ovs_bgp_neighbor->remote_as && local_as == *ovs_bgp_neighbor->remote_as) {
3303+
ABORT_DB_TXN(txn, BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_REMOTE_AS);
3304+
}
3305+
3306+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, &local_as, 1);
3307+
3308+
if (object_is_peer_group(ovs_bgp_neighbor)) {
3309+
ovs_peer_grp = ovs_bgp_neighbor;
3310+
OVSREC_BGP_NEIGHBOR_FOR_EACH(ovs_bgp_neighbor, idl) {
3311+
if (is_member_of_peer_group(ovs_bgp_neighbor, ovs_peer_grp) &&
3312+
!is_ibgp_peer(ovs_bgp_neighbor, asn) &&
3313+
local_as != *ovs_bgp_neighbor->remote_as)
3314+
{
3315+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, &local_as, 1);
3316+
}
3317+
}
3318+
}
3319+
3320+
END_DB_TXN(txn);
3321+
}
3322+
3323+
static int
3324+
cli_no_neighbor_local_as_cmd_execute(char *vrf_name, const char *argv[])
3325+
{
3326+
const char *peer_str = argv[0];
3327+
const struct ovsrec_bgp_router *bgp_router_context;
3328+
const struct ovsrec_vrf *vrf_row;
3329+
const struct ovsrec_bgp_neighbor *ovs_bgp_neighbor, *ovs_peer_grp;
3330+
struct ovsdb_idl_txn *txn;
3331+
int64_t asn = (int64_t)vty->index;
3332+
3333+
START_DB_TXN(txn);
3334+
3335+
vrf_row = get_ovsrec_vrf_with_name(vrf_name);
3336+
if (!vrf_row) {
3337+
ERRONEOUS_DB_TXN(txn, BGP_ERR_NO_VRF_FOUND);
3338+
}
3339+
3340+
bgp_router_context = get_ovsrec_bgp_router_with_asn(vrf_row, asn);
3341+
if (!bgp_router_context) {
3342+
ERRONEOUS_DB_TXN(txn, BGP_ERR_ROUTER_IS_NOT_CONFIGURED);
3343+
}
3344+
3345+
ovs_bgp_neighbor =
3346+
get_bgp_peer_group_with_bgp_router_and_name(bgp_router_context, peer_str);
3347+
if (!ovs_bgp_neighbor) {
3348+
ABORT_DB_TXN(txn, BGP_ERR_NEIGHBOR_IS_NOT_CONFIGURED);
3349+
}
3350+
3351+
if(ovs_bgp_neighbor->bgp_peer_group) {
3352+
ABORT_DB_TXN(txn, BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER);
3353+
}
3354+
3355+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, NULL, 0);
3356+
3357+
if (object_is_peer_group(ovs_bgp_neighbor)) {
3358+
ovs_peer_grp = ovs_bgp_neighbor;
3359+
OVSREC_BGP_NEIGHBOR_FOR_EACH(ovs_bgp_neighbor, idl) {
3360+
if (is_member_of_peer_group(ovs_bgp_neighbor, ovs_peer_grp)) {
3361+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, NULL, 0);
3362+
}
3363+
}
3364+
}
3365+
3366+
END_DB_TXN(txn);
3367+
}
3368+
32403369
DEFUN(neighbor_local_as,
32413370
neighbor_local_as_cmd,
32423371
NEIGHBOR_CMD2 "local-as " CMD_AS_RANGE,
@@ -3245,8 +3374,7 @@ DEFUN(neighbor_local_as,
32453374
"Specify a local-as number\n"
32463375
"AS number used as local AS\n")
32473376
{
3248-
report_unimplemented_command(vty, argc, argv);
3249-
return CMD_SUCCESS;
3377+
return cli_neighbor_local_as_cmd_execute(NULL, argv);
32503378
}
32513379

32523380
DEFUN(neighbor_local_as_no_prepend,
@@ -3283,8 +3411,7 @@ DEFUN(no_neighbor_local_as,
32833411
NEIGHBOR_ADDR_STR2
32843412
"Specify a local-as number\n")
32853413
{
3286-
report_unimplemented_command(vty, argc, argv);
3287-
return CMD_SUCCESS;
3414+
return cli_no_neighbor_local_as_cmd_execute(NULL, argv);
32883415
}
32893416

32903417
ALIAS(no_neighbor_local_as,
@@ -3451,6 +3578,7 @@ cli_neighbor_set_peer_group_cmd_execute(char *vrf_name, const char *ip_addr,
34513578
struct ovsdb_idl_txn *txn;
34523579
char *key_timers[2];
34533580
timer_val_t tim_val;
3581+
int64_t asn = (int64_t)vty->index;
34543582

34553583
START_DB_TXN(txn);
34563584

@@ -3460,8 +3588,7 @@ cli_neighbor_set_peer_group_cmd_execute(char *vrf_name, const char *ip_addr,
34603588
}
34613589

34623590
/* This *MUST* be already available. */
3463-
bgp_router_context = get_ovsrec_bgp_router_with_asn(vrf_row,
3464-
(int64_t)vty->index);
3591+
bgp_router_context = get_ovsrec_bgp_router_with_asn(vrf_row, asn);
34653592
if (!bgp_router_context) {
34663593
ERRONEOUS_DB_TXN(txn, BGP_ERR_ROUTER_IS_NOT_CONFIGURED);
34673594
}
@@ -3529,6 +3656,15 @@ cli_neighbor_set_peer_group_cmd_execute(char *vrf_name, const char *ip_addr,
35293656
(int64_t *)&tim_val, ovs_bgp_peer_group->n_timers);
35303657
}
35313658

3659+
if (ovs_bgp_peer_group->n_local_as &&
3660+
!is_ibgp_peer(ovs_bgp_neighbor, asn) &&
3661+
*ovs_bgp_neighbor->remote_as != *ovs_bgp_peer_group->local_as) {
3662+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, ovs_bgp_peer_group->local_as, 1);
3663+
}
3664+
else {
3665+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, NULL, 0);
3666+
}
3667+
35323668
/* Make this peer bound to the peer group. */
35333669
ovsrec_bgp_neighbor_set_bgp_peer_group(ovs_bgp_neighbor,
35343670
ovs_bgp_peer_group);
@@ -3591,8 +3727,11 @@ cli_no_neighbor_set_peer_group_cmd_execute(char *vrf_name,
35913727
ovsrec_bgp_neighbor_delete(ovs_bgp_neighbor);
35923728
} else {
35933729
ovsrec_bgp_neighbor_set_bgp_peer_group(ovs_bgp_neighbor, NULL);
3594-
}
35953730

3731+
if (ovs_bgp_neighbors_peer_group->n_local_as) {
3732+
ovsrec_bgp_neighbor_set_local_as(ovs_bgp_neighbor, NULL, 0);
3733+
}
3734+
}
35963735
} else {
35973736
ABORT_DB_TXN(txn, BGP_ERR_NEIGHBOR_NOT_IN_PEER_GROUP);
35983737
}

vtysh/bgp_vty.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
/* BGP error codes. */
4242
#define BGP_ERR_NO_VRF_FOUND "% VRF is not found"
4343
#define BGP_ERR_ROUTER_IS_NOT_CONFIGURED "% BGP router is not configured"
44-
#define BGP_ERR_NEIGHBOR_IS_NOT_CONFIGURED "% Neighbor is not configured"
44+
#define BGP_ERR_NEIGHBOR_IS_NOT_CONFIGURED "% Neighbor is not configured. Specify remote-AS or peer-group commands first"
4545
#define BGP_ERR_COMMAND_EXIST "% Command exists"
4646
#define BGP_ERR_COMMAND_NOT_EXIST "% Command does not exist"
4747
#define BGP_ERR_PEER_GROUP_IS_NOT_CREATED "% Peer group does not exist. Create the peer-group first"
@@ -59,6 +59,10 @@
5959
#define BGP_ERR_NO_ROUTE_MAP_ENTRY "% Route-map entry is not found"
6060
#define BGP_ERR_NO_COMMUNITY_FILTER_LIST "% Community-filter list is not found"
6161
#define BGP_ERR_EBGP_MULTIHOP_TTL_SECURITY_CONFIG "% Can't configure ebgp-multihop and ttl-security at the same time"
62+
#define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP "% Local-as allowed only for EBGP peers"
63+
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS "% Cannot have local-as same as BGP AS number"
64+
#define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_REMOTE_AS "% Cannot have local-as same as neighbor remote AS number"
65+
#define BGP_ERR_INVALID_FOR_PEER_GROUP_MEMBER "% Invalid command for a peer-group member"
6266

6367
/*
6468
** depending on the outcome of the db transaction, returns

vtysh/vtysh_ovsdb_router_context.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,23 @@ static void vtysh_router_context_bgp_print_nbr_cfg(vtysh_ovsdb_cbmsg_ptr p_msg,
195195

196196
if (nbr_table->update_source) {
197197
if (!pgroup_ptr ||
198-
strcmp(nbr_table->update_source, pgroup_ptr->update_source) != 0){
198+
strcmp(nbr_table->update_source, pgroup_ptr->update_source) != 0){
199199
vtysh_ovsdb_cli_print(p_msg,"%4s %s %s %s %s", "", "neighbor",
200200
neighbor,
201201
"update-source",
202202
(nbr_table->update_source));
203203
}
204204
}
205+
206+
if (nbr_table->n_local_as) {
207+
if (!pgroup_ptr ||
208+
*(nbr_table->local_as) != *(pgroup_ptr->local_as)){
209+
vtysh_ovsdb_cli_print(p_msg,"%4s %s %s %s %lu", "", "neighbor",
210+
neighbor,
211+
"local-as",
212+
*(nbr_table->local_as));
213+
}
214+
}
205215
}
206216

207217
/*-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)