aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libtle_glue/gateway.h
diff options
context:
space:
mode:
authorJianfeng Tan <henry.tjf@antfin.com>2019-11-18 06:59:50 +0000
committerJianfeng Tan <henry.tjf@antfin.com>2020-03-05 01:31:33 +0800
commit78c896b3b3127515478090c19447e27dc406427e (patch)
treed6d67d4683e9ca0409f9984a834547a572fb5310 /lib/libtle_glue/gateway.h
parente4380f4866091fd92a7a57667dd938a99144f9cd (diff)
Signed-off-by: Jianfeng Tan <henry.tjf@antfin.com> Signed-off-by: Jielong Zhou <jielong.zjl@antfin.com> Signed-off-by: Jian Zhang <wuzai.zj@antfin.com> Signed-off-by: Chen Zhao <winters.zc@antfin.com> Change-Id: I55c39de4c6cd30f991f35631eb507f770230f08e
Diffstat (limited to 'lib/libtle_glue/gateway.h')
-rw-r--r--lib/libtle_glue/gateway.h96
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/libtle_glue/gateway.h b/lib/libtle_glue/gateway.h
new file mode 100644
index 0000000..29de6b1
--- /dev/null
+++ b/lib/libtle_glue/gateway.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019 Ant Financial Services Group.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _TLE_GATEWAY_H_
+#define _TLE_GATEWAY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline bool
+is_ipv4_loopback_addr(in_addr_t addr, struct glue_ctx *ctx)
+{
+ if (addr == ctx->ipv4 || addr == htonl(INADDR_LOOPBACK))
+ return true;
+ else
+ return false;
+}
+
+static inline bool
+is_ipv6_loopback_addr(const struct in6_addr *addr, struct glue_ctx *ctx)
+{
+ if (memcmp(addr, &ctx->ipv6, sizeof(struct in6_addr)) == 0 ||
+ IN6_IS_ADDR_LOOPBACK(addr) ||
+ (IN6_IS_ADDR_V4COMPAT(addr) &&
+ addr->__in6_u.__u6_addr32[3] == htonl(INADDR_LOOPBACK)) ||
+ (IN6_IS_ADDR_V4MAPPED(addr) &&
+ addr->__in6_u.__u6_addr32[3] == htonl(INADDR_LOOPBACK)))
+ return true;
+ else
+ return false;
+}
+
+static inline const struct in_addr *
+ipv4_gateway_lookup(void *data, const struct in_addr *addr)
+{
+ uint8_t ls;
+ struct glue_ctx *ctx = data;
+
+ if (is_ipv4_loopback_addr(addr->s_addr, ctx))
+ return addr;
+
+ ls = 32 - ctx->ipv4_ml;
+ if ((addr->s_addr << ls) == (ctx->ipv4 << ls))
+ return addr;
+
+ if (ctx->ipv4_gw.s_addr != 0)
+ return &ctx->ipv4_gw;
+
+ return addr;
+}
+
+static inline const struct in6_addr *
+ipv6_gateway_lookup(void *data, const struct in6_addr *addr)
+{
+ uint8_t ls;
+ struct glue_ctx *ctx = data;
+
+ if (is_ipv6_loopback_addr(addr, ctx))
+ return addr;
+
+ if (ctx->ipv6_ml <= 64) {
+ ls = 64 - ctx->ipv6_ml;
+ if ((*(const uint64_t*)addr << ls) ==
+ (*(const uint64_t*)&ctx->ipv6 << ls))
+ return addr;
+ } else if (*(const uint64_t*)addr == *(const uint64_t*)&ctx->ipv6) {
+ ls = 128 - ctx->ipv6_ml;
+ if ((*((const uint64_t*)addr + 1) << ls) ==
+ (*((const uint64_t*)&ctx->ipv6 + 1) << ls))
+ return addr;
+ }
+
+ if (!IN6_IS_ADDR_UNSPECIFIED(&ctx->ipv6_gw))
+ return &ctx->ipv6_gw;
+
+ return addr;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TLE_GATEWAY_H_ */