pespin submitted this change.

View Change

Approvals: Jenkins Builder: Verified pespin: Looks good to me, approved lynxis lazus: Looks good to me, but someone else must approve osmith: Looks good to me, but someone else must approve
ggsn: Support announcing APN MTU over PCO

This is only useful for IPv4 (or IPv4v6) APNs.
IPv6 APNs obtain this information from SLAAC RA.

Related: OS#6298
Related: SYS#7122
Change-Id: I8532acfffadda9e83962b30e4f6b17eb8b3362ac
---
M ggsn/ggsn.c
M ggsn/ggsn.h
M ggsn/ggsn_vty.c
M ggsn/pco.c
4 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 650150a..4dc0c94 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -107,6 +107,7 @@
apn->cfg.name = talloc_strdup(apn, name);
apn->cfg.shutdown = true;
apn->cfg.tx_gpdu_seq = true;
+ apn->cfg.mtu = MAX_DESIRED_APN_MTU;
INIT_LLIST_HEAD(&apn->cfg.name_list);

llist_add_tail(&apn->list, &ggsn->apn_list);
diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h
index 7a3204f..7073575 100644
--- a/ggsn/ggsn.h
+++ b/ggsn/ggsn.h
@@ -21,6 +21,19 @@
#define APN_TYPE_IPv6 0x02 /* v6-only */
#define APN_TYPE_IPv4v6 0x04 /* v4v6 dual-stack */

+/* The maximum sane MTU over GTP-U somebody may wish to configure:
+ * 9000 bytes aka jumbo frames. */
+#define MAX_POSSIBLE_APN_MTU 9000
+
+/* See 3GPP TS 23.060 Annex C: */
+#define ETHERNET_MTU 1500
+#define IPV4_HDR_MAX_SIZE 60
+#define IPV6_HDR_MAX_SIZE 40 /* Assume no extension headers in general... */
+#define UDP_HDR_MAX_SIZE 8
+#define GTPU_HDR_MAX_SIZE 12 /* Assume no extension headers in general... */
+#define MAX_DESIRED_APN_MTU ((ETHERNET_MTU) - (GTPU_HDR_MAX_SIZE) - (UDP_HDR_MAX_SIZE) - (IPV4_HDR_MAX_SIZE))
+/* MAX_DESIRED_APN_MTU = 1500 - 60 - 8 - 12 = 1500 - 80 = 1420 */
+
struct ggsn_ctx;

struct apn_ctx_ip {
@@ -70,6 +83,8 @@
bool shutdown;
/* transmit G-PDU sequence numbers (true) or not (false) */
bool tx_gpdu_seq;
+ /* MTU announced to the UE */
+ uint16_t mtu;
} cfg;

/* corresponding tun device */
diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c
index 3e139c3..eda0096 100644
--- a/ggsn/ggsn_vty.c
+++ b/ggsn/ggsn_vty.c
@@ -419,6 +419,22 @@
return CMD_SUCCESS;
}

+/* MAX_POSSIBLE_APN_MTU = 9000
+ * MAX_DESIRED_APN_MTU = 1420 */
+DEFUN(cfg_apn_mtu, cfg_apn_mtu_cmd,
+ "mtu (<0-" OSMO_STRINGIFY_VAL(MAX_POSSIBLE_APN_MTU) ">|default)",
+ "Configure announced MTU\n"
+ "MTU of the APN, announced to the UE\n"
+ "Default value of the MTU of the APN (1420)\n")
+{
+ struct apn_ctx *apn = (struct apn_ctx *) vty->index;
+ if (strcmp(argv[0], "default") == 0)
+ apn->cfg.mtu = MAX_DESIRED_APN_MTU;
+ else
+ apn->cfg.mtu = atoi(argv[0]);
+ return CMD_SUCCESS;
+}
+
DEFUN(cfg_apn_ipup_script, cfg_apn_ipup_script_cmd,
"ipup-script PATH",
"Configure name/path of ip-up script\n"
@@ -689,6 +705,8 @@
VTY_NEWLINE);
}

+ vty_out(vty, " mtu %" PRIu16 "%s", apn->cfg.mtu, VTY_NEWLINE);
+
if (!apn->cfg.tx_gpdu_seq)
vty_out(vty, " no g-pdu tx-sequence-numbers%s", VTY_NEWLINE);

@@ -1066,6 +1084,7 @@
install_element(APN_NODE, &cfg_apn_type_support_cmd);
install_element(APN_NODE, &cfg_apn_no_type_support_cmd);
install_element(APN_NODE, &cfg_apn_tun_dev_name_cmd);
+ install_element(APN_NODE, &cfg_apn_mtu_cmd);
install_element(APN_NODE, &cfg_apn_ipup_script_cmd);
install_element(APN_NODE, &cfg_apn_no_ipup_script_cmd);
install_element(APN_NODE, &cfg_apn_ipdown_script_cmd);
diff --git a/ggsn/pco.c b/ggsn/pco.c
index c71f07d..b4ffacb 100644
--- a/ggsn/pco.c
+++ b/ggsn/pco.c
@@ -198,6 +198,13 @@
LOGPPDP(LOGL_NOTICE, pdp, "MS requested IPv4 DNS, but APN has none configured\n");
}

+static void process_pco_element_link_mtu_ipv4(const struct pco_element *pco_elem, struct msgb *resp,
+ const struct apn_ctx *apn, struct pdp_t *pdp)
+{
+ const uint16_t val_be = osmo_htons(apn->cfg.mtu);
+ msgb_t16lv_put(resp, PCO_P_IPv4_LINK_MTU, 2, (const uint8_t *)&val_be);
+}
+
static void process_pco_element(const struct pco_element *pco_elem, struct msgb *resp,
const struct apn_ctx *apn, struct pdp_t *pdp)
{
@@ -217,6 +224,9 @@
case PCO_P_DNS_IPv4_ADDR:
process_pco_element_dns_ipv4(pco_elem, resp, apn, pdp);
break;
+ case PCO_P_IPv4_LINK_MTU:
+ process_pco_element_link_mtu_ipv4(pco_elem, resp, apn, pdp);
+ break;
default:
LOGPPDP(LOGL_INFO, pdp, "Unknown/Unimplemented PCO Protocol 0x%04x: %s\n",
protocol_id, osmo_hexdump_nospc(pco_elem->data, pco_elem->length));

To view, visit change 38457. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-MessageType: merged
Gerrit-Project: osmo-ggsn
Gerrit-Branch: master
Gerrit-Change-Id: I8532acfffadda9e83962b30e4f6b17eb8b3362ac
Gerrit-Change-Number: 38457
Gerrit-PatchSet: 5
Gerrit-Owner: pespin <pespin@sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de>
Gerrit-Reviewer: laforge <laforge@osmocom.org>
Gerrit-Reviewer: lynxis lazus <lynxis@fe80.eu>
Gerrit-Reviewer: osmith <osmith@sysmocom.de>
Gerrit-Reviewer: pespin <pespin@sysmocom.de>