pespin has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ggsn/+/38457?usp=email )
Change subject: ggsn: Support announcing APN MTU over PCO ......................................................................
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(-)
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
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));