summaryrefslogtreecommitdiff
path: root/bgpd
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_fsm.c3
-rw-r--r--bgpd/bgp_nht.c19
-rw-r--r--bgpd/bgp_packet.c3
-rw-r--r--bgpd/bgp_route.c6
-rw-r--r--bgpd/bgp_vty.c53
-rw-r--r--bgpd/bgp_zebra.c73
-rw-r--r--bgpd/bgpd.c5
7 files changed, 107 insertions, 55 deletions
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 0e3ed9f0d1..1a30cb37f4 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -2163,6 +2163,9 @@ bgp_establish(struct peer_connection *connection)
peer->established++;
bgp_fsm_change_status(connection, Established);
+ if (peer->last_reset == PEER_DOWN_WAITING_OPEN)
+ peer->last_reset = 0;
+
/* bgp log-neighbor-changes of neighbor Up */
if (CHECK_FLAG(peer->bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) {
struct vrf *vrf = vrf_lookup_by_id(peer->bgp->vrf_id);
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index 164e2300c0..2ef7ec97e3 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -1278,6 +1278,25 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
}
LIST_FOREACH (path, &(bnc->paths), nh_thread) {
+ /*
+ * Currently when a peer goes down, bgp immediately
+ * sees this via the interface events( if it is directly
+ * connected). And in this case it takes and puts on
+ * a special peer queue all path info's associated with
+ * but these items are not yet processed typically when
+ * the nexthop is being handled here. Thus we end
+ * up in a situation where the process Queue for BGP
+ * is being asked to look at the same path info multiple
+ * times. Let's just cut to the chase here and if
+ * the bnc has a peer associated with it and the path info
+ * being looked at uses that peer and the peer is no
+ * longer established we know the path_info is being
+ * handled elsewhere and we do not need to process
+ * it here at all since the pathinfo is going away
+ */
+ if (peer && path->peer == peer && !peer_established(peer->connection))
+ continue;
+
if (path->type == ZEBRA_ROUTE_BGP &&
(path->sub_type == BGP_ROUTE_NORMAL ||
path->sub_type == BGP_ROUTE_STATIC ||
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 0780b4f72d..f8726ffff9 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1225,6 +1225,9 @@ void bgp_capability_send(struct peer *peer, afi_t afi, safi_t safi,
const char *hostname = cmd_hostname_get();
const char *domainname = cmd_domainname_get();
+ if (!peer)
+ return;
+
if (!peer_established(peer->connection))
return;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f2e61e1e7f..e932738cd4 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -3885,6 +3885,12 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
BGP_PATH_ATTR_CHANGED);
UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
UNSET_FLAG(new_select->flags, BGP_PATH_LINK_BW_CHG);
+ } else {
+ /*
+ * Ensure that on uninstall that the INSTALL_PENDING
+ * is no longer set
+ */
+ UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
}
/* call bmp hook for loc-rib route update / withdraw after flags were
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 04b9ce5ea6..e18f6443b5 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -122,6 +122,9 @@ FRR_CFG_DEFAULT_BOOL(BGP_ENFORCE_FIRST_AS,
{ .val_bool = false, .match_version = "< 9.1", },
{ .val_bool = true },
);
+FRR_CFG_DEFAULT_BOOL(BGP_RR_ALLOW_OUTBOUND_POLICY,
+ { .val_bool = false },
+);
DEFINE_HOOK(bgp_inst_config_write,
(struct bgp *bgp, struct vty *vty),
@@ -622,6 +625,8 @@ int bgp_get_vty(struct bgp **bgp, as_t *as, const char *name,
BGP_FLAG_DYNAMIC_CAPABILITY);
if (DFLT_BGP_ENFORCE_FIRST_AS)
SET_FLAG((*bgp)->flags, BGP_FLAG_ENFORCE_FIRST_AS);
+ if (DFLT_BGP_RR_ALLOW_OUTBOUND_POLICY)
+ SET_FLAG((*bgp)->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
ret = BGP_SUCCESS;
}
@@ -17575,12 +17580,6 @@ DEFUN (bgp_redistribute_ipv4_ospf,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
@@ -17634,12 +17633,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
@@ -17697,12 +17690,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
@@ -17767,12 +17754,6 @@ DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
@@ -17842,13 +17823,7 @@ DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- } else if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
- strlen("table-direct")) == 0) {
+ if (strncmp(argv[idx_ospf_table]->arg, "table-direct", strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
if (instance == RT_TABLE_MAIN ||
instance == RT_TABLE_LOCAL) {
@@ -17911,12 +17886,6 @@ DEFUN (no_bgp_redistribute_ipv4_ospf,
if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
protocol = ZEBRA_ROUTE_OSPF;
else {
- if (bgp->vrf_id != VRF_DEFAULT) {
- vty_out(vty,
- "%% Only default BGP instance can use '%s'\n",
- argv[idx_ospf_table]->arg);
- return CMD_WARNING_CONFIG_FAILED;
- }
if (strncmp(argv[idx_ospf_table]->arg, "table-direct",
strlen("table-direct")) == 0) {
protocol = ZEBRA_ROUTE_TABLE_DIRECT;
@@ -19816,10 +19785,12 @@ int bgp_config_write(struct vty *vty)
}
}
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
- vty_out(vty,
- " bgp route-reflector allow-outbound-policy\n");
- }
+ if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) !=
+ SAVE_BGP_RR_ALLOW_OUTBOUND_POLICY)
+ vty_out(vty, " %sbgp route-reflector allow-outbound-policy\n",
+ CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY) ? ""
+ : "no ");
+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID))
vty_out(vty, " bgp bestpath compare-routerid\n");
if (CHECK_FLAG(bgp->flags, BGP_FLAG_COMPARE_AIGP))
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 8e8616c155..1669aabc60 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1674,11 +1674,23 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
- (pi->type == ZEBRA_ROUTE_BGP
- && (pi->sub_type == BGP_ROUTE_NORMAL
- || pi->sub_type == BGP_ROUTE_IMPORTED)))
- bgp_zebra_route_install(dest, pi, bgp, true,
- NULL, false);
+ (pi->type == ZEBRA_ROUTE_BGP && (pi->sub_type == BGP_ROUTE_NORMAL ||
+ pi->sub_type == BGP_ROUTE_IMPORTED))) {
+ bool is_add = true;
+
+ if (bgp->table_map[afi][safi].name) {
+ struct attr local_attr = *pi->attr;
+ struct bgp_path_info local_info = *pi;
+
+ local_info.attr = &local_attr;
+
+ is_add = bgp_table_map_apply(bgp->table_map[afi][safi].map,
+ bgp_dest_get_prefix(dest),
+ &local_info);
+ }
+
+ bgp_zebra_route_install(dest, pi, bgp, is_add, NULL, false);
+ }
}
/* Announce routes of any bgp subtype of a table to zebra */
@@ -2042,11 +2054,34 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
/* Return if already redistribute flag is set. */
if (instance) {
- if (redist_check_instance(&zclient->mi_redist[afi][type],
- instance))
- return CMD_WARNING;
+ if (type == ZEBRA_ROUTE_TABLE_DIRECT) {
+ /*
+ * When redistribution type is `table-direct` the
+ * instance means `table identification`.
+ *
+ * `table_id` support 32bit integers, however since
+ * `instance` is being overloaded to `table_id` it
+ * will only be possible to use the first 65535
+ * entries.
+ *
+ * Also the ZAPI must also support `int`
+ * (see `zebra_redistribute_add`).
+ */
+ struct redist_table_direct table = {
+ .table_id = instance,
+ .vrf_id = bgp->vrf_id,
+ };
+ if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) !=
+ NULL)
+ return CMD_WARNING;
+
+ redist_add_table_direct(&zclient->mi_redist[afi][type], &table);
+ } else {
+ if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
+ return CMD_WARNING;
- redist_add_instance(&zclient->mi_redist[afi][type], instance);
+ redist_add_instance(&zclient->mi_redist[afi][type], instance);
+ }
} else {
if (vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING;
@@ -2174,10 +2209,22 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
/* Return if zebra connection is disabled. */
if (instance) {
- if (!redist_check_instance(&zclient->mi_redist[afi][type],
- instance))
- return CMD_WARNING;
- redist_del_instance(&zclient->mi_redist[afi][type], instance);
+ if (type == ZEBRA_ROUTE_TABLE_DIRECT) {
+ struct redist_table_direct table = {
+ .table_id = instance,
+ .vrf_id = bgp->vrf_id,
+ };
+ if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) ==
+ NULL)
+ return CMD_WARNING;
+
+ redist_del_table_direct(&zclient->mi_redist[afi][type], &table);
+ } else {
+ if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
+ return CMD_WARNING;
+
+ redist_del_instance(&zclient->mi_redist[afi][type], instance);
+ }
} else {
if (!vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 6de403b30c..edf90d3dd8 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2026,8 +2026,11 @@ struct peer *peer_create(union sockunion *su, const char *conf_if,
if (bgp->autoshutdown)
peer_flag_set(peer, PEER_FLAG_SHUTDOWN);
/* Set up peer's events and timers. */
- else if (!active && peer_active(peer->connection))
+ else if (!active && peer_active(peer->connection)) {
+ if (peer->last_reset == PEER_DOWN_NOAFI_ACTIVATED)
+ peer->last_reset = 0;
bgp_timer_set(peer->connection);
+ }
bgp_peer_gr_flags_update(peer);
BGP_GR_ROUTER_DETECT_AND_SEND_CAPABILITY_TO_ZEBRA(bgp, bgp->peer);