@@ -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+
32403369DEFUN(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
32523380DEFUN(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
32903417ALIAS(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 }
0 commit comments