summaryrefslogtreecommitdiff
path: root/proto/bgp/bgp.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2019-08-06 15:29:06 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2019-08-06 15:29:06 +0200
commite2b530aa729f9c5973e498b45dd6f55ab669d1ac (patch)
treea82e256afe93d3fe242d17838c4accd4ccf7e81b /proto/bgp/bgp.c
parentf6a6a77640a9749c79a91300d130ba6b5941d408 (diff)
BGP: Improve reconfiguration
Several BGP channel options (including 'next hop self') could be reconfigured without session reset, with just route refeed/refresh. The patch improves reconfiguration code to do it that way.
Diffstat (limited to 'proto/bgp/bgp.c')
-rw-r--r--proto/bgp/bgp.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 5a403b40..c08e5ee9 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -2054,23 +2054,35 @@ bgp_reconfigure(struct proto *P, struct proto_config *CF)
#define IGP_TABLE(cf, sym) ((cf)->igp_table_##sym ? (cf)->igp_table_##sym ->table : NULL )
static int
-bgp_channel_reconfigure(struct channel *C, struct channel_config *CC)
+bgp_channel_reconfigure(struct channel *C, struct channel_config *CC, int *import_changed, int *export_changed)
{
struct bgp_channel *c = (void *) C;
struct bgp_channel_config *new = (void *) CC;
struct bgp_channel_config *old = c->cf;
- if (memcmp(((byte *) old) + sizeof(struct channel_config),
- ((byte *) new) + sizeof(struct channel_config),
- /* Remaining items must be checked separately */
- OFFSETOF(struct bgp_channel_config, rest) - sizeof(struct channel_config)))
+ if ((new->secondary != old->secondary) ||
+ (new->gr_able != old->gr_able) ||
+ (new->llgr_able != old->llgr_able) ||
+ (new->llgr_time != old->llgr_time) ||
+ (new->ext_next_hop != old->ext_next_hop) ||
+ (new->add_path != old->add_path) ||
+ (new->import_table != old->import_table) ||
+ (IGP_TABLE(new, ip4) != IGP_TABLE(old, ip4)) ||
+ (IGP_TABLE(new, ip6) != IGP_TABLE(old, ip6)))
return 0;
- /* Check change in IGP tables */
- if ((IGP_TABLE(old, ip4) != IGP_TABLE(new, ip4)) ||
- (IGP_TABLE(old, ip6) != IGP_TABLE(new, ip6)))
+ if (new->mandatory && !old->mandatory && (C->channel_state != CS_UP))
return 0;
+ if (new->gw_mode != old->gw_mode)
+ *import_changed = 1;
+
+ if (!ipa_equal(new->next_hop_addr, old->next_hop_addr) ||
+ (new->next_hop_self != old->next_hop_self) ||
+ (new->next_hop_keep != old->next_hop_keep) ||
+ (new->missing_lladdr != old->missing_lladdr))
+ *export_changed = 1;
+
c->cf = new;
return 1;
}