summaryrefslogtreecommitdiffstats
path: root/bfdd/ptm_adapter.c
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2018-07-11 21:04:51 +0200
committerRafael Zalamena <rzalamena@opensourcerouting.org>2018-08-08 23:25:08 +0200
commita375de5c460c7e3b31cf5668af238b517785a24e (patch)
tree14050fe170b5ceff0ebc7b8b9c396b987c37c258 /bfdd/ptm_adapter.c
parentbfdd: send replay request on zebra connection (diff)
downloadfrr-a375de5c460c7e3b31cf5668af238b517785a24e.tar.xz
frr-a375de5c460c7e3b31cf5668af238b517785a24e.zip
bfdd: free zebra clients data on unregistration
Avoid a memory leak on client daemons restart by getting rid of old registrations. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'bfdd/ptm_adapter.c')
-rw-r--r--bfdd/ptm_adapter.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 28e332626..b2c6b8e2d 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -63,6 +63,7 @@ static int _ptm_msg_read(struct stream *msg, int command,
static struct ptm_client *pc_lookup(uint32_t pid);
static struct ptm_client *pc_new(uint32_t pid);
+static void pc_free(struct ptm_client *pc);
static struct ptm_client_notification *pcn_new(struct ptm_client *pc,
struct bfd_session *bs);
static struct ptm_client_notification *pcn_lookup(struct ptm_client *pc,
@@ -73,6 +74,7 @@ static void pcn_free(struct ptm_client_notification *pcn);
static void bfdd_dest_register(struct stream *msg);
static void bfdd_dest_deregister(struct stream *msg);
static void bfdd_client_register(struct stream *msg);
+static void bfdd_client_deregister(struct stream *msg);
/*
* Functions
@@ -487,6 +489,32 @@ stream_failure:
log_error("%s: failed to register client", __func__);
}
+/*
+ * header: command, VRF
+ * l: pid
+ */
+static void bfdd_client_deregister(struct stream *msg)
+{
+ struct ptm_client *pc;
+ uint32_t pid;
+
+ /* Find or allocate process context data. */
+ STREAM_GETL(msg, pid);
+
+ pc = pc_lookup(pid);
+ if (pc == NULL) {
+ log_debug("%s: failed to find client: %u", __func__, pid);
+ return;
+ }
+
+ pc_free(pc);
+
+ return;
+
+stream_failure:
+ log_error("%s: failed to deregister client", __func__);
+}
+
static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid)
{
struct stream *msg = zc->ibuf;
@@ -505,6 +533,9 @@ static int bfdd_replay(int cmd, struct zclient *zc, uint16_t len, vrf_id_t vid)
case ZEBRA_BFD_CLIENT_REGISTER:
bfdd_client_register(msg);
break;
+ case ZEBRA_BFD_CLIENT_DEREGISTER:
+ bfdd_client_deregister(msg);
+ break;
default:
log_debug("%s: invalid message type %u", __func__, rcmd);
@@ -593,6 +624,23 @@ static struct ptm_client *pc_new(uint32_t pid)
return pc;
}
+static void pc_free(struct ptm_client *pc)
+{
+ struct ptm_client_notification *pcn;
+
+ if (pc == NULL)
+ return;
+
+ TAILQ_REMOVE(&pcqueue, pc, pc_entry);
+
+ while (!TAILQ_EMPTY(&pc->pc_pcnqueue)) {
+ pcn = TAILQ_FIRST(&pc->pc_pcnqueue);
+ pcn_free(pcn);
+ }
+
+ XFREE(MTYPE_BFDD_CONTROL, pc);
+}
+
static struct ptm_client_notification *pcn_new(struct ptm_client *pc,
struct bfd_session *bs)
{