summaryrefslogtreecommitdiff
path: root/nhrpd/nhrp_interface.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2020-03-26 17:33:53 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2020-11-23 17:16:35 +0000
commitfef2ed139d140f551cdfcbb21c5a023dea2e02cb (patch)
treeec4a61a4744d0cc2924bb964f4b77017cf865c0f /nhrpd/nhrp_interface.c
parent2332790973b2ad4364c5d818e2dc72c4c329e73a (diff)
nhrpd: cache config may disappear if iface not present at startup
When interface not present at config time, store separately the list of config parameters. Then, when interface is ready and an address has been configured, the nbma setting is done. Reversely, when interface disappears, there is no need to keep the maps present, then keep only the configuration. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'nhrpd/nhrp_interface.c')
-rw-r--r--nhrpd/nhrp_interface.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c
index 0ed2371eb0..0e7d4e7931 100644
--- a/nhrpd/nhrp_interface.c
+++ b/nhrpd/nhrp_interface.c
@@ -23,6 +23,10 @@
DEFINE_MTYPE_STATIC(NHRPD, NHRP_IF, "NHRP interface")
+static void nhrp_interface_update_cache_config(struct interface *ifp,
+ bool available,
+ uint8_t family);
+
static int nhrp_if_new_hook(struct interface *ifp)
{
struct nhrp_interface *nifp;
@@ -311,11 +315,68 @@ int nhrp_ifp_destroy(struct interface *ifp)
{
debugf(NHRP_DEBUG_IF, "if-delete: %s", ifp->name);
+ nhrp_interface_update_cache_config(ifp, false, AF_INET);
+ nhrp_interface_update_cache_config(ifp, false, AF_INET6);
nhrp_interface_update(ifp);
return 0;
}
+struct map_ctx {
+ int family;
+ bool enabled;
+};
+
+static void interface_config_update_nhrp_map(struct nhrp_cache_config *cc, void *data)
+{
+ struct map_ctx *ctx = data;
+ struct interface *ifp = cc->ifp;
+ struct nhrp_cache *c;
+ union sockunion nbma_addr;
+
+ if (sockunion_family(&cc->remote_addr) != ctx->family)
+ return;
+
+ /* gre layer not ready */
+ if (ifp->vrf_id == VRF_UNKNOWN)
+ return;
+
+ c = nhrp_cache_get(ifp, &cc->remote_addr, ctx->enabled ? 1 : 0);
+ if (!c && !ctx->enabled)
+ return;
+ /* suppress */
+ if (!ctx->enabled) {
+ if (c && c->map) {
+ nhrp_cache_update_binding(c, c->cur.type, -1,
+ nhrp_peer_get(ifp, &nbma_addr), 0, NULL);
+ }
+ return;
+ }
+ /* create */
+ c->map = 1;
+ if (cc->type == NHRP_CACHE_LOCAL)
+ nhrp_cache_update_binding(c, NHRP_CACHE_LOCAL, 0, NULL, 0,
+ NULL);
+ else {
+ nhrp_cache_update_binding(c, NHRP_CACHE_STATIC, 0,
+ nhrp_peer_get(ifp, &cc->nbma), 0,
+ NULL);
+ }
+}
+
+static void nhrp_interface_update_cache_config(struct interface *ifp, bool available, uint8_t family)
+{
+ struct map_ctx mapctx;
+
+ mapctx = (struct map_ctx){
+ .family = family,
+ .enabled = available
+ };
+ nhrp_cache_config_foreach(ifp, interface_config_update_nhrp_map,
+ &mapctx);
+
+}
+
int nhrp_ifp_up(struct interface *ifp)
{
debugf(NHRP_DEBUG_IF, "if-up: %s", ifp->name);
@@ -345,7 +406,7 @@ int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS)
nhrp_interface_update_address(
ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
-
+ nhrp_interface_update_cache_config(ifc->ifp, true, PREFIX_FAMILY(ifc->address));
return 0;
}