summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2021-02-20 19:25:15 +0200
committerDonatas Abraitis <donatas.abraitis@gmail.com>2021-02-28 19:49:43 +0200
commite84c59af5bcdcc80112bae4937fdeaa10bb95bbc (patch)
tree44c7a1f033854ea5c6af437b4bd9f1f84053e697
parent8cf565010c5c741133778b9135ef9a668fae9aec (diff)
bgpd: Activate ipv6-unicast for peer automatically if globally defined
When you use a single BGP session for both IPv4 and IPv6 it's a bit annoying going into ipv6 address-family and explicitly activating it. Let's get this automatically if enabled with `bgp default ipv6-unicast`. Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
-rw-r--r--bgpd/bgp_nb_config.c19
-rw-r--r--bgpd/bgp_network.c2
-rw-r--r--bgpd/bgp_vty.c83
-rw-r--r--bgpd/bgp_vty.h6
-rw-r--r--bgpd/bgpd.c55
-rw-r--r--bgpd/bgpd.h6
6 files changed, 111 insertions, 60 deletions
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
index 721ce5b5c6..d75a6a65e1 100644
--- a/bgpd/bgp_nb_config.c
+++ b/bgpd/bgp_nb_config.c
@@ -3146,8 +3146,7 @@ int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify(
return NB_OK;
str2sockunion(peer_str, &su);
- ret = peer_remote_as(bgp, &su, NULL, &as, as_type, AFI_IP,
- SAFI_UNICAST);
+ ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
if (bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret)
< 0)
return NB_ERR_INCONSISTENCY;
@@ -3202,8 +3201,7 @@ int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify(
as = yang_dnode_get_uint32(args->dnode, NULL);
str2sockunion(peer_str, &su);
- ret = peer_remote_as(bgp, &su, NULL, &as, as_type, AFI_IP,
- SAFI_UNICAST);
+ ret = peer_remote_as(bgp, &su, NULL, &as, as_type);
if (bgp_nb_errmsg_return(args->errmsg, args->errmsg_len, ret)
< 0)
return NB_ERR_INCONSISTENCY;
@@ -4370,8 +4368,7 @@ int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args)
"./neighbor-remote-as/remote-as");
}
- if (peer_conf_interface_create(bgp, peer_str, AFI_IP,
- SAFI_UNICAST, v6_only,
+ if (peer_conf_interface_create(bgp, peer_str, v6_only,
peer_grp_str, as_type, as,
args->errmsg, args->errmsg_len))
return NB_ERR_INCONSISTENCY;
@@ -4440,9 +4437,9 @@ int bgp_neighbors_unnumbered_neighbor_v6only_modify(
v6_only = yang_dnode_get_bool(args->dnode, NULL);
- if (peer_conf_interface_create(
- bgp, peer_str, AFI_IP, SAFI_UNICAST, v6_only, NULL,
- AS_UNSPECIFIED, 0, args->errmsg, args->errmsg_len))
+ if (peer_conf_interface_create(bgp, peer_str, v6_only, NULL,
+ AS_UNSPECIFIED, 0, args->errmsg,
+ args->errmsg_len))
return NB_ERR_INCONSISTENCY;
break;
@@ -5174,8 +5171,6 @@ void bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_apply_finish(
int ret;
as_t as = 0;
struct peer *peer = NULL;
- afi_t afi = AFI_IP;
- safi_t safi = SAFI_UNICAST;
bgp = nb_running_get_entry(args->dnode, NULL, true);
peer_str = yang_dnode_get_string(args->dnode, "../interface");
@@ -5185,7 +5180,7 @@ void bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_apply_finish(
peer = peer_lookup_by_conf_if(bgp, peer_str);
- ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi, safi);
+ ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type);
if (ret < 0 && !peer) {
snprintf(args->errmsg, args->errmsg_len,
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
index be2c474493..be3a8f3c1f 100644
--- a/bgpd/bgp_network.c
+++ b/bgpd/bgp_network.c
@@ -554,7 +554,7 @@ static int bgp_accept(struct thread *thread)
peer1->host);
peer = peer_create(&su, peer1->conf_if, peer1->bgp, peer1->local_as,
- peer1->as, peer1->as_type, 0, 0, NULL);
+ peer1->as, peer1->as_type, NULL);
hash_release(peer->bgp->peerhash, peer);
hash_get(peer->bgp->peerhash, peer, hash_alloc_intern);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 9e8065691e..0654adb646 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -3726,6 +3726,29 @@ DEFPY (no_bgp_bestpath_bw,
return CMD_SUCCESS;
}
+/* "no bgp default ipv6-unicast". */
+DEFUN(no_bgp_default_ipv6_unicast, no_bgp_default_ipv6_unicast_cmd,
+ "no bgp default ipv6-unicast", NO_STR
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Activate ipv6-unicast for a peer by default\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ UNSET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6);
+ return CMD_SUCCESS;
+}
+
+DEFUN(bgp_default_ipv6_unicast, bgp_default_ipv6_unicast_cmd,
+ "bgp default ipv6-unicast",
+ "BGP specific commands\n"
+ "Configure BGP defaults\n"
+ "Activate ipv6-unicast for a peer by default\n")
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ SET_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6);
+ return CMD_SUCCESS;
+}
+
/* "no bgp default ipv4-unicast". */
DEFUN (no_bgp_default_ipv4_unicast,
no_bgp_default_ipv4_unicast_cmd,
@@ -4367,10 +4390,10 @@ DEFUN_YANG(neighbor_remote_as,
return nb_cli_apply_changes(vty, base_xpath);
}
-int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, afi_t afi,
- safi_t safi, bool v6only,
- const char *peer_group_name, int as_type,
- as_t as, char *errmsg, size_t errmsg_len)
+int peer_conf_interface_create(struct bgp *bgp, const char *conf_if,
+ bool v6only, const char *peer_group_name,
+ int as_type, as_t as, char *errmsg,
+ size_t errmsg_len)
{
struct peer *peer;
struct peer_group *group;
@@ -4387,16 +4410,10 @@ int peer_conf_interface_create(struct bgp *bgp, const char *conf_if, afi_t afi,
peer = peer_lookup_by_conf_if(bgp, conf_if);
if (peer) {
if (as_type != AS_UNSPECIFIED)
- ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type,
- afi, safi);
+ ret = peer_remote_as(bgp, NULL, conf_if, &as, as_type);
} else {
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4)
- && afi == AFI_IP && safi == SAFI_UNICAST)
- peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
- as_type, 0, 0, NULL);
- else
- peer = peer_create(NULL, conf_if, bgp, bgp->as, as,
- as_type, afi, safi, NULL);
+ peer = peer_create(NULL, conf_if, bgp, bgp->as, as, as_type,
+ NULL);
if (!peer) {
snprintf(errmsg, errmsg_len,
@@ -16799,18 +16816,36 @@ static void bgp_config_write_peer_af(struct vty *vty, struct bgp *bgp,
}
} else {
if (peer->afc[afi][safi]) {
- if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
- if (CHECK_FLAG(bgp->flags,
- BGP_FLAG_NO_DEFAULT_IPV4)) {
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && safi == SAFI_UNICAST) {
+ if (afi == AFI_IP
+ && CHECK_FLAG(bgp->flags,
+ BGP_FLAG_NO_DEFAULT_IPV4)) {
+ vty_out(vty, " neighbor %s activate\n",
+ addr);
+ } else if (afi == AFI_IP6
+ && !CHECK_FLAG(
+ bgp->flags,
+ BGP_FLAG_DEFAULT_IPV6)) {
vty_out(vty, " neighbor %s activate\n",
addr);
}
- } else
+ } else {
vty_out(vty, " neighbor %s activate\n", addr);
+ }
} else {
- if ((afi == AFI_IP) && (safi == SAFI_UNICAST)) {
- if (!CHECK_FLAG(bgp->flags,
- BGP_FLAG_NO_DEFAULT_IPV4)) {
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && safi == SAFI_UNICAST) {
+ if (afi == AFI_IP
+ && !CHECK_FLAG(bgp->flags,
+ BGP_FLAG_NO_DEFAULT_IPV4)) {
+ vty_out(vty,
+ " no neighbor %s activate\n",
+ addr);
+ } else if (afi == AFI_IP6
+ && CHECK_FLAG(
+ bgp->flags,
+ BGP_FLAG_DEFAULT_IPV6)) {
vty_out(vty,
" no neighbor %s activate\n",
addr);
@@ -17244,6 +17279,10 @@ int bgp_config_write(struct vty *vty)
if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
vty_out(vty, " no bgp default ipv4-unicast\n");
+ /* BGP default ipv6-unicast. */
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6))
+ vty_out(vty, " bgp default ipv6-unicast\n");
+
/* BGP default local-preference. */
if (bgp->default_local_pref != BGP_DEFAULT_LOCAL_PREF)
vty_out(vty, " bgp default local-preference %u\n",
@@ -17914,6 +17953,10 @@ void bgp_vty_init(void)
install_element(BGP_NODE, &no_bgp_default_ipv4_unicast_cmd);
install_element(BGP_NODE, &bgp_default_ipv4_unicast_cmd);
+ /* "no bgp default ipv6-unicast" commands. */
+ install_element(BGP_NODE, &no_bgp_default_ipv6_unicast_cmd);
+ install_element(BGP_NODE, &bgp_default_ipv6_unicast_cmd);
+
/* "bgp network import-check" commands. */
install_element(BGP_NODE, &bgp_network_import_check_cmd);
install_element(BGP_NODE, &bgp_network_import_check_exact_cmd);
diff --git a/bgpd/bgp_vty.h b/bgpd/bgp_vty.h
index 85619dd074..251bdc3fe3 100644
--- a/bgpd/bgp_vty.h
+++ b/bgpd/bgp_vty.h
@@ -205,9 +205,9 @@ extern int peer_local_interface_cfg(struct bgp *bgp, const char *ip_str,
const char *str, char *errmsg,
size_t errmsg_len);
extern int peer_conf_interface_create(struct bgp *bgp, const char *conf_if,
- afi_t afi, safi_t safi, bool v6only,
- const char *peer_group_name, int as_type,
- as_t as, char *errmsg, size_t errmsg_len);
+ bool v6only, const char *peer_group_name,
+ int as_type, as_t as, char *errmsg,
+ size_t errmsg_len);
extern int peer_flag_modify_nb(struct bgp *bgp, const char *ip_str,
struct peer *peer, uint32_t flag, bool set,
char *errmsg, size_t errmsg_len);
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 07ca247ee6..c259fcdc7b 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -1467,8 +1467,10 @@ void peer_xfer_config(struct peer *peer_dst, struct peer *peer_src)
for (afidx = BGP_AF_START; afidx < BGP_AF_MAX; afidx++) {
paf = peer_src->peer_af_array[afidx];
- if (paf != NULL)
- peer_af_create(peer_dst, paf->afi, paf->safi);
+ if (paf != NULL) {
+ if (!peer_af_find(peer_dst, paf->afi, paf->safi))
+ peer_af_create(peer_dst, paf->afi, paf->safi);
+ }
}
/* update-source apply */
@@ -1682,12 +1684,13 @@ void bgp_recalculate_all_bestpaths(struct bgp *bgp)
*/
struct peer *peer_create(union sockunion *su, const char *conf_if,
struct bgp *bgp, as_t local_as, as_t remote_as,
- int as_type, afi_t afi, safi_t safi,
- struct peer_group *group)
+ int as_type, struct peer_group *group)
{
int active;
struct peer *peer;
char buf[SU_ADDRSTRLEN];
+ afi_t afi;
+ safi_t safi;
peer = peer_new(bgp);
if (conf_if) {
@@ -1746,9 +1749,23 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
SET_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE);
- if (afi && safi) {
- peer->afc[afi][safi] = 1;
- peer_af_create(peer, afi, safi);
+ /* If address family is IPv4 and `bgp default ipv4-unicast` (default),
+ * then activate the neighbor for this AF.
+ * If address family is IPv6 and `bgp default ipv6-unicast`
+ * (non-default), then activate the neighbor for this AF.
+ */
+ FOREACH_AFI_SAFI (afi, safi) {
+ if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) {
+ if ((afi == AFI_IP
+ && !CHECK_FLAG(bgp->flags,
+ BGP_FLAG_NO_DEFAULT_IPV4))
+ || (afi == AFI_IP6
+ && CHECK_FLAG(bgp->flags,
+ BGP_FLAG_DEFAULT_IPV6))) {
+ peer->afc[afi][safi] = 1;
+ peer_af_create(peer, afi, safi);
+ }
+ }
}
/* auto shutdown if configured */
@@ -1877,7 +1894,7 @@ void peer_as_change(struct peer *peer, as_t as, int as_specified)
/* If peer does not exist, create new one. If peer already exists,
set AS number to the peer. */
int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
- as_t *as, int as_type, afi_t afi, safi_t safi)
+ as_t *as, int as_type)
{
struct peer *peer;
as_t local_as;
@@ -1945,16 +1962,7 @@ int peer_remote_as(struct bgp *bgp, union sockunion *su, const char *conf_if,
else
local_as = bgp->as;
- /* If this is IPv4 unicast configuration and "no bgp default
- ipv4-unicast" is specified. */
-
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4)
- && afi == AFI_IP && safi == SAFI_UNICAST)
- peer_create(su, conf_if, bgp, local_as, *as, as_type, 0,
- 0, NULL);
- else
- peer_create(su, conf_if, bgp, local_as, *as, as_type,
- afi, safi, NULL);
+ peer_create(su, conf_if, bgp, local_as, *as, as_type, NULL);
}
return 0;
@@ -2561,6 +2569,8 @@ struct peer_group *peer_group_get(struct bgp *bgp, const char *name)
group->conf = peer_new(bgp);
if (!CHECK_FLAG(bgp->flags, BGP_FLAG_NO_DEFAULT_IPV4))
group->conf->afc[AFI_IP][SAFI_UNICAST] = 1;
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_DEFAULT_IPV6))
+ group->conf->afc[AFI_IP6][SAFI_UNICAST] = 1;
XFREE(MTYPE_BGP_PEER_HOST, group->conf->host);
group->conf->host = XSTRDUP(MTYPE_BGP_PEER_HOST, name);
group->conf->group = group;
@@ -2995,7 +3005,7 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
}
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
- group->conf->as_type, 0, 0, group);
+ group->conf->as_type, group);
peer = peer_lock(peer); /* group->peer list reference */
listnode_add(group->peer, peer);
@@ -3007,7 +3017,10 @@ int peer_group_bind(struct bgp *bgp, union sockunion *su, struct peer *peer,
FOREACH_AFI_SAFI (afi, safi) {
if (group->conf->afc[afi][safi]) {
peer->afc[afi][safi] = 1;
- peer_af_create(peer, afi, safi);
+
+ if (!peer_af_find(peer, afi, safi))
+ peer_af_create(peer, afi, safi);
+
peer_group2peer_config_copy_af(group, peer, afi,
safi);
} else if (peer->afc[afi][safi])
@@ -3806,7 +3819,7 @@ struct peer *peer_create_bind_dynamic_neighbor(struct bgp *bgp,
/* Create peer first; we've already checked group config is valid. */
peer = peer_create(su, NULL, bgp, bgp->as, group->conf->as,
- group->conf->as_type, 0, 0, group);
+ group->conf->as_type, group);
if (!peer)
return NULL;
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index e79dccdab8..c0bb8cc634 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -477,6 +477,7 @@ struct bgp {
#define BGP_FLAG_SHUTDOWN (1 << 27)
#define BGP_FLAG_SUPPRESS_FIB_PENDING (1 << 28)
#define BGP_FLAG_SUPPRESS_DUPLICATES (1 << 29)
+#define BGP_FLAG_DEFAULT_IPV6 (1 << 30)
enum global_mode GLOBAL_GR_FSM[BGP_GLOBAL_GR_MODE]
[BGP_GLOBAL_GR_EVENT_CMD];
@@ -1916,8 +1917,7 @@ extern bool peer_active(struct peer *);
extern bool peer_active_nego(struct peer *);
extern void bgp_recalculate_all_bestpaths(struct bgp *bgp);
extern struct peer *peer_create(union sockunion *, const char *, struct bgp *,
- as_t, as_t, int, afi_t, safi_t,
- struct peer_group *);
+ as_t, as_t, int, struct peer_group *);
extern struct peer *peer_create_accept(struct bgp *);
extern void peer_xfer_config(struct peer *dst, struct peer *src);
extern char *peer_uptime(time_t uptime2, char *buf, size_t len, bool use_json,
@@ -1985,7 +1985,7 @@ extern bool bgp_update_delay_configured(struct bgp *);
extern int bgp_afi_safi_peer_exists(struct bgp *bgp, afi_t afi, safi_t safi);
extern void peer_as_change(struct peer *, as_t, int);
extern int peer_remote_as(struct bgp *, union sockunion *, const char *, as_t *,
- int, afi_t, safi_t);
+ int);
extern int peer_group_remote_as(struct bgp *, const char *, as_t *, int);
extern int peer_delete(struct peer *peer);
extern void peer_notify_unconfig(struct peer *peer);