aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2018-01-30 16:16:33 +0100
committerPau Espin Pedrol <pespin@sysmocom.de>2018-01-30 22:50:14 +0100
commitdddbbaaee1bfb0890c22a1cd9385d9ba45848997 (patch)
treee64629479410b2b569730670317e3a1ea3ddfeb4
parent134855c45ebb01c83f1d6abcd00e9a12fb960108 (diff)
ggsn.c: cb_tun_ind: Don't drop packets targeting pdp ctx ll addr
-rw-r--r--ggsn/ggsn.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index fed8f73..caf6151 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -726,6 +726,7 @@ static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
struct ip6_hdr *ip6h = (struct ip6_hdr *)pack;
struct ippool_t *pool;
char straddr[INET6_ADDRSTRLEN];
+ uint8_t pref_offset;
switch (iph->version) {
case 4:
@@ -739,9 +740,12 @@ static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
/* Due to the fact that 3GPP requires an allocation of a
* /64 prefix to each MS, we must instruct
* ippool_getip() below to match only the leading /64
- * prefix, i.e. the first 8 bytes of the address */
+ * prefix, i.e. the first 8 bytes of the address. If the ll addr
+ * is used, then the match should be done on the trailing 64
+ * bits. */
dst.len = 8;
- dst.v6 = ip6h->ip6_dst;
+ pref_offset = IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_dst) ? 8 : 0;
+ memcpy(&dst.v6, ((uint8_t*)&ip6h->ip6_dst) + pref_offset, 8);
pool = apn->v6.pool;
break;
default: