Change in libosmo-abis[master]: add ipa ping/pong keepalive for OML/RSL links between bts and bsc

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

osmith gerrit-no-reply at lists.osmocom.org
Wed Jan 29 08:01:58 UTC 2020


osmith has submitted this change. ( https://gerrit.osmocom.org/c/libosmo-abis/+/14743 )

Change subject: add ipa ping/pong keepalive for OML/RSL links between bts and bsc
......................................................................

add ipa ping/pong keepalive for OML/RSL links between bts and bsc

Patch-by: ewild, osmith
Related: OS#4070
Change-Id: I30e3bd601e55355aaf738ee2f2c44c1ec2c46c6a
Depends: (libosmo-abis) Ie453fdee8bfd7fc1a3f1ed67ef0331f0abb1d59b
---
M TODO-RELEASE
M include/osmocom/abis/e1_input.h
M src/e1_input_vty.c
M src/input/ipaccess.c
4 files changed, 204 insertions(+), 22 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  fixeria: Looks good to me, but someone else must approve
  osmith: Looks good to me, approved



diff --git a/TODO-RELEASE b/TODO-RELEASE
index d0852fc..e2f62ef 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -7,3 +7,4 @@
 # If any interfaces have been added since the last public release: c:r:a + 1.
 # If any interfaces have been removed or changed since the last public release: c:r:0.
 #library	what		description / commit summary line
+libosmo-abis	API change	major: add parameter to struct e1inp_line
diff --git a/include/osmocom/abis/e1_input.h b/include/osmocom/abis/e1_input.h
index 00b4aaa..4362f50 100644
--- a/include/osmocom/abis/e1_input.h
+++ b/include/osmocom/abis/e1_input.h
@@ -123,6 +123,8 @@
 		struct {
 			/* ip.access driver has one fd for each ts */
 			struct osmo_fd fd;
+			/* ipa keep-alive */
+			struct osmo_fsm_inst* ka_fsm;
 		} ipaccess;
 		struct {
 			/* DAHDI driver has one fd for each ts */
@@ -197,11 +199,14 @@
 	char *sock_path;
 	struct rate_ctr_group *rate_ctr;
 
-	/* keepalive configuration */
+	/* tcp keepalive configuration */
 	int keepalive_num_probes; /* 0: disable, num, or E1INP_USE_DEFAULT */
 	int keepalive_idle_timeout; /* secs, or E1INP_USE_DEFAULT */
 	int keepalive_probe_interval; /* secs or E1INP_USE_DEFAULT */
 
+	/* ipa ping/pong keepalive params */
+	struct ipa_keepalive_params *ipa_kap;
+
 	/* array of timestlots */
 	struct e1inp_ts ts[NUM_E1_TS];
 	unsigned int num_ts;
diff --git a/src/e1_input_vty.c b/src/e1_input_vty.c
index a1943e6..8d89d04 100644
--- a/src/e1_input_vty.c
+++ b/src/e1_input_vty.c
@@ -38,6 +38,7 @@
 #include <osmocom/vty/telnet_interface.h>
 
 #include <osmocom/abis/e1_input.h>
+#include <osmocom/abis/ipa.h>
 
 /* CONFIG */
 
@@ -169,6 +170,47 @@
 	return set_keepalive_params(vty, atoi(argv[0]), 0, 0, 0);
 }
 
+#define IPA_KEEPALIVE_HELP "Enable IPA PING/PONG keep-alive\n"
+static int set_ipa_keepalive_params(struct vty *vty, int e1_nr, int interval, int wait_for_resp)
+{
+	struct e1inp_line *line = e1inp_line_find(e1_nr);
+
+	if (!line) {
+		vty_out(vty, "%% Line %d doesn't exist%s", e1_nr, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	if (strcmp(line->driver->name, "ipa") != 0) {
+		vty_out(vty, "%% Line %d doesn't use the ipa driver%s", e1_nr, VTY_NEWLINE);
+		return CMD_WARNING;
+	}
+
+	TALLOC_FREE(line->ipa_kap);
+	if (interval) {
+		line->ipa_kap = talloc_zero(line, struct ipa_keepalive_params);
+		line->ipa_kap->wait_for_resp = wait_for_resp;
+		line->ipa_kap->interval = interval;
+	}
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_e1line_ipa_keepalive, cfg_e1_line_ipa_keepalive_cmd,
+	"e1_line <0-255> ipa-keepalive <1-300> <1-300>",
+	E1_LINE_HELP IPA_KEEPALIVE_HELP
+	"Idle interval in seconds before probes are sent\n"
+	"Time to wait for PONG response\n")
+{
+	return set_ipa_keepalive_params(vty, atoi(argv[0]), atoi(argv[1]), atoi(argv[2]));
+}
+
+DEFUN(cfg_e1line_no_ipa_keepalive, cfg_e1_line_no_ipa_keepalive_cmd,
+	"no e1_line <0-255> ipa-keepalive",
+	NO_STR E1_LINE_HELP IPA_KEEPALIVE_HELP)
+{
+	return set_ipa_keepalive_params(vty, atoi(argv[0]), 0, 0);
+}
+
 DEFUN(cfg_e1line_name, cfg_e1_line_name_cmd,
 	"e1_line <0-255> name .LINE",
 	E1_LINE_HELP "Set name for this line\n" "Human readable name\n")
@@ -242,7 +284,10 @@
 				line->keepalive_num_probes,
 				line->keepalive_probe_interval,
 				VTY_NEWLINE);
-
+		if (line->ipa_kap)
+			vty_out(vty, " e1_line %u ipa-keepalive %d %d%s", line->num,
+				line->ipa_kap->interval, line->ipa_kap->wait_for_resp,
+				VTY_NEWLINE);
 	}
 
 	const char *ipa_bind = e1inp_ipa_get_bind_addr();
@@ -398,6 +443,8 @@
 	install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_cmd);
 	install_element(L_E1INP_NODE, &cfg_e1_line_keepalive_params_cmd);
 	install_element(L_E1INP_NODE, &cfg_e1_line_no_keepalive_cmd);
+	install_element(L_E1INP_NODE, &cfg_e1_line_ipa_keepalive_cmd);
+	install_element(L_E1INP_NODE, &cfg_e1_line_no_ipa_keepalive_cmd);
 
 	install_element(L_E1INP_NODE, &cfg_ipa_bind_cmd);
 
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 9eff2f1..e1936af 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -59,14 +59,31 @@
 #define DEFAULT_TCP_KEEPALIVE_INTERVAL     3
 #define DEFAULT_TCP_KEEPALIVE_RETRY_COUNT  10
 
+static inline struct e1inp_ts *ipaccess_line_ts(struct osmo_fd *bfd, struct e1inp_line *line)
+{
+	if (bfd->priv_nr == E1INP_SIGN_OML)
+		return e1inp_line_ipa_oml_ts(line);
+	else
+		return e1inp_line_ipa_rsl_ts(line, bfd->priv_nr - E1INP_SIGN_RSL);
+}
+
+static inline void ipaccess_keepalive_fsm_cleanup(struct e1inp_ts *e1i_ts)
+{
+	struct osmo_fsm_inst *ka_fsm;
+
+	ka_fsm = e1i_ts->driver.ipaccess.ka_fsm;
+	if (ka_fsm) {
+		ipa_keepalive_fsm_stop(ka_fsm);
+		e1i_ts->driver.ipaccess.ka_fsm = NULL;
+	}
+}
+
 static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line)
 {
 	int ret = 1;
-	struct e1inp_ts *e1i_ts;
-	if (bfd->priv_nr == E1INP_SIGN_OML)
-		e1i_ts = e1inp_line_ipa_oml_ts(line);
-	else
-		e1i_ts = e1inp_line_ipa_rsl_ts(line, bfd->priv_nr - E1INP_SIGN_RSL);
+	struct e1inp_ts *e1i_ts = ipaccess_line_ts(bfd, line);
+
+	ipaccess_keepalive_fsm_cleanup(e1i_ts);
 
 	/* Error case: we did not see any ID_RESP yet for this socket. */
 	if (bfd->fd != -1) {
@@ -87,6 +104,80 @@
 	return ret;
 }
 
+static void ipa_bsc_keepalive_write_server_cb(struct osmo_fsm_inst *fi, void *conn, struct msgb *msg)
+{
+	struct osmo_fd *bfd = (struct osmo_fd *)conn;
+	write(bfd->fd, msg->data, msg->len);
+	msgb_free(msg);
+}
+
+static int ipa_bsc_keepalive_timeout_cb(struct osmo_fsm_inst *fi, void *data)
+{
+	struct osmo_fd *bfd = (struct osmo_fd *)data;
+
+	if (bfd->fd == -1)
+		return 1;
+
+	ipaccess_drop(bfd, (struct e1inp_line *)bfd->data);
+	return 1;
+}
+
+static void ipaccess_bsc_keepalive_fsm_alloc(struct e1inp_ts *e1i_ts, struct osmo_fd *bfd, const char *id)
+{
+	struct e1inp_line *line = e1i_ts->line;
+	struct osmo_fsm_inst *ka_fsm;
+
+	ipaccess_keepalive_fsm_cleanup(e1i_ts);
+	if (!line->ipa_kap)
+		return;
+
+	ka_fsm = ipa_generic_conn_alloc_keepalive_fsm(tall_ipa_ctx, bfd, line->ipa_kap, id);
+	e1i_ts->driver.ipaccess.ka_fsm = ka_fsm;
+	if (!ka_fsm)
+		return;
+
+	ipa_keepalive_fsm_set_timeout_cb(ka_fsm, ipa_bsc_keepalive_timeout_cb);
+	ipa_keepalive_fsm_set_send_cb(ka_fsm, ipa_bsc_keepalive_write_server_cb);
+	ipa_keepalive_fsm_start(ka_fsm);
+}
+
+static void ipa_bts_keepalive_write_client_cb(struct osmo_fsm_inst *fi, void *conn, struct msgb *msg) {
+	struct ipa_client_conn *link = (struct ipa_client_conn *)conn;
+	int ret = 0;
+
+	ret = ipa_send(link->ofd->fd, msg->data, msg->len);
+	if (ret != msg->len) {
+		LOGP(DLINP, LOGL_ERROR, "cannot send message. Reason: %s\n", strerror(errno));
+	}
+	msgb_free(msg);
+}
+
+static void update_fd_settings(struct e1inp_line *line, int fd);
+static void ipaccess_bts_updown_cb(struct ipa_client_conn *link, int up);
+
+static int ipa_bts_keepalive_timeout_cb(struct osmo_fsm_inst *fi, void *conn) {
+	ipaccess_bts_updown_cb(conn, false);
+	return 1;
+}
+
+static void ipaccess_bts_keepalive_fsm_alloc(struct e1inp_ts *e1i_ts, struct ipa_client_conn *client, const char *id)
+{
+	struct e1inp_line *line = e1i_ts->line;
+	struct osmo_fsm_inst *ka_fsm;
+
+	ipaccess_keepalive_fsm_cleanup(e1i_ts);
+	if (!line->ipa_kap)
+		return;
+
+	ka_fsm = ipa_client_conn_alloc_keepalive_fsm(client, line->ipa_kap, id);
+	e1i_ts->driver.ipaccess.ka_fsm = ka_fsm;
+	if (!ka_fsm)
+		return;
+
+	ipa_keepalive_fsm_set_timeout_cb(ka_fsm, ipa_bts_keepalive_timeout_cb);
+	ipa_keepalive_fsm_set_send_cb(ka_fsm, ipa_bts_keepalive_write_client_cb);
+}
+
 /* Returns -1 on error, and 0 or 1 on success. If -1 or 1 is returned, line has
  * been released and should not be used anymore by the caller. */
 static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
@@ -98,6 +189,14 @@
 	struct e1inp_sign_link *sign_link;
 	char *unitid;
 	int len, ret;
+	struct e1inp_ts *e1i_ts;
+	struct osmo_fsm_inst *ka_fsm;
+
+	/* peek the pong for our keepalive fsm */
+	e1i_ts = ipaccess_line_ts(bfd, line);
+	ka_fsm = e1i_ts->driver.ipaccess.ka_fsm;
+	if (ka_fsm && msg_type == IPAC_MSGT_PONG)
+		ipa_keepalive_fsm_pong_received(ka_fsm);
 
 	/* Handle IPA PING, PONG and ID_ACK messages. */
 	ret = ipa_ccm_rcvmsg_base(msg, bfd);
@@ -165,9 +264,12 @@
 					"closing socket.\n");
 				goto err;
 			}
+
+			ipaccess_bsc_keepalive_fsm_alloc(e1i_ts, bfd, "oml_bsc_to_bts");
+
 		} else if (bfd->priv_nr == E1INP_SIGN_RSL) {
 			struct e1inp_ts *ts;
-                        struct osmo_fd *newbfd;
+			struct osmo_fd *newbfd;
 			struct e1inp_line *new_line;
 
 			sign_link =
@@ -209,6 +311,9 @@
 			}
 			/* now we can release the dummy RSL line. */
 			e1inp_line_put(line);
+
+			e1i_ts = ipaccess_line_ts(newbfd, new_line);
+			ipaccess_bsc_keepalive_fsm_alloc(e1i_ts, newbfd, "rsl_bsc_to_bts");
 			return 1;
 		}
 		break;
@@ -238,11 +343,7 @@
 	struct msgb *msg = NULL;
 	int ret, rc;
 
-	if (bfd->priv_nr == E1INP_SIGN_OML)
-		e1i_ts = e1inp_line_ipa_oml_ts(line);
-	else
-		e1i_ts = e1inp_line_ipa_rsl_ts(line, bfd->priv_nr - E1INP_SIGN_RSL);
-
+	e1i_ts = ipaccess_line_ts(bfd, line);
 	ret = ipa_msg_recv_buffered(bfd->fd, &msg, &e1i_ts->pending_msg);
 	if (ret < 0) {
 		if (ret == -EAGAIN)
@@ -312,6 +413,17 @@
 {
 	struct e1inp_ts *e1i_ts = sign_link->ts;
 	struct osmo_fd *bfd = &e1i_ts->driver.ipaccess.fd;
+	struct e1inp_line *line = e1i_ts->line;
+
+	/* line might not exist if != bsc||bts */
+	if (line) {
+		/* depending on caller the fsm might be dead */
+		struct osmo_fsm_inst* ka_fsm = ipaccess_line_ts(bfd, line)->driver.ipaccess.ka_fsm;
+		if (ka_fsm)
+			ipa_keepalive_fsm_stop(ka_fsm);
+
+	}
+
 	return e1inp_close_socket(e1i_ts, sign_link, bfd);
 }
 
@@ -331,11 +443,7 @@
 	struct msgb *msg;
 	int ret;
 
-	if (bfd->priv_nr == E1INP_SIGN_OML)
-		e1i_ts = e1inp_line_ipa_oml_ts(line);
-	else
-		e1i_ts = e1inp_line_ipa_rsl_ts(line, bfd->priv_nr - E1INP_SIGN_RSL);
-
+	e1i_ts = ipaccess_line_ts(bfd, line);
 	bfd->when &= ~BSC_FD_WRITE;
 
 	/* get the next msg for this timeslot */
@@ -378,6 +486,7 @@
 	msgb_free(msg);
 	return ret;
 err:
+	ipaccess_keepalive_fsm_cleanup(e1i_ts);
 	ipaccess_drop(bfd, line);
 	msgb_free(msg);
 	return ret;
@@ -684,10 +793,14 @@
 {
 	struct e1inp_line *line = link->line;
 
-        if (up) {
-                update_fd_settings(line, link->ofd->fd);
-                return;
-        }
+	if (up) {
+		struct osmo_fsm_inst *ka_fsm = ipaccess_line_ts(link->ofd, line)->driver.ipaccess.ka_fsm;
+
+		update_fd_settings(line, link->ofd->fd);
+		if (ka_fsm && line->ipa_kap)
+			ipa_keepalive_fsm_start(ka_fsm);
+		return;
+	}
 
 	if (line->ops->sign_link_down)
 		line->ops->sign_link_down(line);
@@ -701,10 +814,19 @@
 	struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
 	struct msgb *rmsg;
 	int ret = 0;
+	/* line might not exist if != bsc||bts */
+	struct e1inp_line *line = link->line;
 
 	/* special handling for IPA CCM. */
 	if (hh->proto == IPAC_PROTO_IPACCESS) {
 		uint8_t msg_type = *(msg->l2h);
+		struct osmo_fsm_inst* ka_fsm = NULL;
+
+		/* peek the pong for our keepalive fsm */
+		if (line && msg_type == IPAC_MSGT_PONG) {
+			ka_fsm = ipaccess_line_ts(link->ofd, line)->driver.ipaccess.ka_fsm;
+			ipa_keepalive_fsm_pong_received(ka_fsm);
+		}
 
 		/* ping, pong and acknowledgment cases. */
 		ret = ipa_ccm_rcvmsg_bts_base(msg, link->ofd);
@@ -895,6 +1017,7 @@
 	}
 	case E1INP_LINE_R_BTS: {
 		struct ipa_client_conn *link;
+		struct e1inp_ts *e1i_ts;
 
 		LOGP(DLINP, LOGL_NOTICE, "enabling ipaccess BTS mode, "
 		     "OML connecting to %s:%u\n", line->ops->cfg.ipa.addr,
@@ -922,6 +1045,9 @@
 			ipa_client_conn_destroy(link);
 			return -EIO;
 		}
+
+		e1i_ts = e1inp_line_ipa_oml_ts(line);
+		ipaccess_bts_keepalive_fsm_alloc(e1i_ts, link, "oml_bts_to_bsc");
 		ret = 0;
 		break;
 	}
@@ -944,6 +1070,7 @@
 				uint8_t trx_nr)
 {
 	struct ipa_client_conn *rsl_link;
+	struct e1inp_ts *e1i_ts = e1inp_line_ipa_rsl_ts(line, trx_nr);
 
 	if (E1INP_SIGN_RSL+trx_nr-1 >= NUM_E1_TS) {
 		LOGP(DLINP, LOGL_ERROR, "cannot create RSL BTS link: "
@@ -972,6 +1099,8 @@
 		ipa_client_conn_destroy(rsl_link);
 		return -EIO;
 	}
+
+	ipaccess_bts_keepalive_fsm_alloc(e1i_ts, rsl_link, "rsl_bts_to_bsc");
 	return 0;
 }
 

-- 
To view, visit https://gerrit.osmocom.org/c/libosmo-abis/+/14743
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: libosmo-abis
Gerrit-Branch: master
Gerrit-Change-Id: I30e3bd601e55355aaf738ee2f2c44c1ec2c46c6a
Gerrit-Change-Number: 14743
Gerrit-PatchSet: 12
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-Assignee: osmith <osmith at sysmocom.de>
Gerrit-Reviewer: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <axilirator at gmail.com>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: osmith <osmith at sysmocom.de>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200129/304308a7/attachment.htm>


More information about the gerrit-log mailing list