mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
synced 2025-10-23 08:22:07 +00:00
ggsn: Support announcing APN MTU over ICMPv6 RA
Related: OS#6298 Related: SYS#7122 Change-Id: I8bb67915dd5f39ad9ffb80e5aaf9af1e7d70c96c
This commit is contained in:
@@ -774,7 +774,7 @@ static int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len)
|
||||
/* daddr: all-routers multicast addr */
|
||||
if (IN6_ARE_ADDR_EQUAL(&ip6h->ip6_dst, &all_router_mcast_addr))
|
||||
return handle_router_mcast(pdp->gsn, pdp, &peer->addr.v6,
|
||||
&apn->v6_lladdr, pack, len);
|
||||
&apn->v6_lladdr, apn->cfg.mtu, pack, len);
|
||||
break;
|
||||
case 4:
|
||||
peer = pdp_get_peer_ipv(pdp, false);
|
||||
|
26
lib/icmpv6.c
26
lib/icmpv6.c
@@ -94,11 +94,13 @@ struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr)
|
||||
* \returns callee-allocated message buffer containing router advertisement */
|
||||
static struct msgb *icmpv6_construct_ra(const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr,
|
||||
const struct in6_addr *prefix)
|
||||
const struct in6_addr *prefix,
|
||||
uint32_t mtu)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc_headroom(512,128, "IPv6 RA");
|
||||
struct icmpv6_radv_hdr *ra;
|
||||
struct icmpv6_opt_prefix *ra_opt_pref;
|
||||
struct icmpv6_opt_mtu *ra_opt_mtu;
|
||||
|
||||
OSMO_ASSERT(msg);
|
||||
|
||||
@@ -135,6 +137,25 @@ static struct msgb *icmpv6_construct_ra(const struct in6_addr *saddr,
|
||||
ra_opt_pref->res2 = 0;
|
||||
memcpy(ra_opt_pref->prefix, prefix, sizeof(ra_opt_pref->prefix));
|
||||
|
||||
/* RFC4861 Section 4.6.4, MTU */
|
||||
ra_opt_mtu = (struct icmpv6_opt_mtu *) msgb_put(msg, sizeof(*ra_opt_mtu));
|
||||
ra_opt_mtu->hdr.type = 5; /* RFC4861 4.6.4 */
|
||||
ra_opt_mtu->hdr.len = 1; /* RFC4861 4.6.4 */
|
||||
ra_opt_mtu->reserved = 0;
|
||||
ra_opt_mtu->mtu = htonl(mtu);
|
||||
|
||||
/* The Prefix is contained in the Prefix Information Option of
|
||||
* the Router Advertisements and shall have the A-flag set
|
||||
* and the L-flag cleared */
|
||||
ra_opt_pref->a = 1;
|
||||
ra_opt_pref->l = 0;
|
||||
ra_opt_pref->res = 0;
|
||||
/* The lifetime of the prefix shall be set to infinity */
|
||||
ra_opt_pref->valid_lifetime = htonl(GGSN_AdvValidLifetime);
|
||||
ra_opt_pref->preferred_lifetime = htonl(GGSN_AdvPreferredLifetime);
|
||||
ra_opt_pref->res2 = 0;
|
||||
memcpy(ra_opt_pref->prefix, prefix, sizeof(ra_opt_pref->prefix));
|
||||
|
||||
/* checksum */
|
||||
ra->hdr.csum = icmpv6_prepend_ip6hdr(msg, saddr, daddr);
|
||||
|
||||
@@ -194,6 +215,7 @@ struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned
|
||||
int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
const struct in6_addr *pdp_prefix,
|
||||
const struct in6_addr *own_ll_addr,
|
||||
uint32_t mtu,
|
||||
const uint8_t *pack, unsigned len)
|
||||
{
|
||||
const struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
|
||||
@@ -230,7 +252,7 @@ int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
/* Send router advertisement from GGSN link-local
|
||||
* address to MS link-local address, including prefix
|
||||
* allocated to this PDP context */
|
||||
msg = icmpv6_construct_ra(own_ll_addr, &ip6h->ip6_src, pdp_prefix);
|
||||
msg = icmpv6_construct_ra(own_ll_addr, &ip6h->ip6_src, pdp_prefix, mtu);
|
||||
/* Send the constructed RA to the MS */
|
||||
gtp_data_req(gsn, pdp, msgb_data(msg), msgb_length(msg));
|
||||
msgb_free(msg);
|
||||
|
@@ -81,6 +81,13 @@ struct icmpv6_opt_prefix {
|
||||
uint8_t prefix[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* RFC4861 Section 4.6.4 */
|
||||
struct icmpv6_opt_mtu {
|
||||
struct icmpv6_opt_hdr hdr;
|
||||
uint16_t reserved;
|
||||
uint32_t mtu;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
uint16_t icmpv6_prepend_ip6hdr(struct msgb *msg, const struct in6_addr *saddr,
|
||||
const struct in6_addr *daddr);
|
||||
|
||||
@@ -89,6 +96,7 @@ struct msgb *icmpv6_construct_rs(const struct in6_addr *saddr);
|
||||
int handle_router_mcast(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
const struct in6_addr *pdp_prefix,
|
||||
const struct in6_addr *own_ll_addr,
|
||||
uint32_t mtu,
|
||||
const uint8_t *pack, unsigned len);
|
||||
|
||||
struct icmpv6_radv_hdr *icmpv6_validate_router_adv(const uint8_t *pack, unsigned len);
|
||||
|
Reference in New Issue
Block a user