-
Notifications
You must be signed in to change notification settings - Fork 727
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Decode aliyun's toa and encode it to the format of DPVS. It's a workaround when the traffic of DPVS is from aliyun l4lb.
- Loading branch information
1 parent
d683835
commit af47c02
Showing
1 changed file
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
From 55e8e5da2b4b0893d36cb3f621bedf9833c4ea50 Mon Sep 17 00:00:00 2001 | ||
From: wangyetong <[email protected]> | ||
Date: Thu, 14 Sep 2023 15:33:42 +0800 | ||
Subject: [PATCH] added dcdn toa | ||
|
||
--- | ||
include/ipvs/conn.h | 5 +++++ | ||
include/ipvs/proto_tcp.h | 2 ++ | ||
src/ipvs/ip_vs_proto_tcp.c | 54 +++++++++++++++++++++++++++++++++++++++++++++- | ||
3 files changed, 60 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/include/ipvs/conn.h b/include/ipvs/conn.h | ||
index fa0bdeb..88dcb44 100644 | ||
--- a/include/ipvs/conn.h | ||
+++ b/include/ipvs/conn.h | ||
@@ -166,6 +166,11 @@ struct dp_vs_conn { | ||
/* flag for gfwip */ | ||
bool outwall; | ||
|
||
+ /* dcdn toa found or not */ | ||
+ bool dcdn_found; | ||
+ /* dcdn toa address */ | ||
+ struct in_addr dcdn_addr; | ||
+ | ||
} __rte_cache_aligned; | ||
|
||
/* for syn-proxy to save all ack packet in conn before rs's syn-ack arrives */ | ||
diff --git a/include/ipvs/proto_tcp.h b/include/ipvs/proto_tcp.h | ||
index 9f5162a..41d5646 100644 | ||
--- a/include/ipvs/proto_tcp.h | ||
+++ b/include/ipvs/proto_tcp.h | ||
@@ -28,6 +28,7 @@ enum { | ||
TCP_OPT_SACK_PERM = 4, | ||
TCP_OPT_SACK = 5, | ||
TCP_OPT_TIMESTAMP = 8, | ||
+ TCP_OPT_DCDN_ADDR = 28, | ||
TCP_OPT_ADDR = 254, /* non-standard */ | ||
}; | ||
|
||
@@ -35,6 +36,7 @@ enum { | ||
#define TCP_OLEN_TIMESTAMP 10 | ||
#define TCP_OLEN_IP4_ADDR 8 | ||
#define TCP_OLEN_IP6_ADDR 20 | ||
+#define TOA_DCDN_IPV4 1 | ||
|
||
#define TCP_OLEN_TSTAMP_ALIGNED 12 | ||
#define TCP_OLEN_SACK_BASE 2 | ||
diff --git a/src/ipvs/ip_vs_proto_tcp.c b/src/ipvs/ip_vs_proto_tcp.c | ||
index cbb7cb2..2cd889a 100644 | ||
--- a/src/ipvs/ip_vs_proto_tcp.c | ||
+++ b/src/ipvs/ip_vs_proto_tcp.c | ||
@@ -305,6 +305,43 @@ static void tcp_in_remove_ts(struct tcphdr *tcph) | ||
} | ||
} | ||
|
||
+/* check dcdn toa option */ | ||
+static inline int tcp_in_check_toa(struct dp_vs_conn *conn, struct tcphdr *tcph, struct in_addr *addr) | ||
+{ | ||
+ unsigned char *ptr; | ||
+ int len; | ||
+ | ||
+ ptr = (unsigned char *)(tcph + 1); | ||
+ len = (tcph->doff << 2) - sizeof(struct tcphdr); | ||
+ | ||
+ while (len > 0) { | ||
+ int opcode = *ptr++; | ||
+ int opsize; | ||
+ | ||
+ switch (opcode) { | ||
+ case TCP_OPT_EOL: | ||
+ return EDPVS_NOTEXIST; | ||
+ case TCP_OPT_NOP: | ||
+ len--; | ||
+ continue; | ||
+ default: | ||
+ opsize = *ptr++; | ||
+ if (opsize < 2) /* silly options */ | ||
+ return EDPVS_NOTEXIST; | ||
+ if (opsize > len) | ||
+ return EDPVS_NOTEXIST; /* partial options */ | ||
+ if ((opcode == TCP_OPT_DCDN_ADDR) | ||
+ && (*ptr == TOA_DCDN_IPV4) && (opsize == TCP_OLEN_IP4_ADDR - 1) && addr) { | ||
+ memcpy(addr, ptr + 1, sizeof(struct in_addr)); | ||
+ return EDPVS_OK; | ||
+ } | ||
+ ptr += opsize - 2; | ||
+ len -= opsize; | ||
+ } | ||
+ } | ||
+ return EDPVS_NOTEXIST; | ||
+} | ||
+ | ||
static inline int tcp_in_add_toa(struct dp_vs_conn *conn, struct rte_mbuf *mbuf, | ||
struct tcphdr *tcph) | ||
{ | ||
@@ -382,7 +419,10 @@ static inline int tcp_in_add_toa(struct dp_vs_conn *conn, struct rte_mbuf *mbuf, | ||
|
||
if (conn->af == AF_INET) { | ||
struct tcpopt_ip4_addr *toa_ip4 = (struct tcpopt_ip4_addr *)(tcph + 1); | ||
- toa_ip4->addr = conn->caddr.in; | ||
+ if (conn->dcdn_found) | ||
+ toa_ip4->addr = conn->dcdn_addr; | ||
+ else | ||
+ toa_ip4->addr = conn->caddr.in; | ||
} | ||
else { | ||
struct tcpopt_ip6_addr *toa_ip6 = (struct tcpopt_ip6_addr *)(tcph + 1); | ||
@@ -694,9 +734,13 @@ static int tcp_fnat_in_handler(struct dp_vs_proto *proto, | ||
struct dp_vs_conn *conn, struct rte_mbuf *mbuf) | ||
{ | ||
struct tcphdr *th; | ||
+ struct in_addr dcdn_addr; | ||
/* af/mbuf may be changed for nat64 which in af is ipv6 and out is ipv4 */ | ||
int af = tuplehash_out(conn).af; | ||
int iphdrlen = ((AF_INET6 == af) ? ip6_hdrlen(mbuf): ip4_hdrlen(mbuf)); | ||
+#ifdef CONFIG_DPVS_IPVS_DEBUG | ||
+ char dcdn_buf[64]; | ||
+#endif | ||
|
||
if (mbuf_may_pull(mbuf, iphdrlen + sizeof(*th)) != 0) | ||
return EDPVS_INVPKT; | ||
@@ -720,6 +764,14 @@ static int tcp_fnat_in_handler(struct dp_vs_proto *proto, | ||
if (th->syn && !th->ack) { | ||
tcp_in_remove_ts(th); | ||
tcp_in_init_seq(conn, mbuf, th); | ||
+ if (tcp_in_check_toa(conn, th, &dcdn_addr) == EDPVS_OK) { | ||
+ conn->dcdn_found = true; | ||
+ conn->dcdn_addr = dcdn_addr; | ||
+#ifdef CONFIG_DPVS_IPVS_DEBUG | ||
+ inet_ntop(AF_INET, &dcdn_addr, dcdn_buf, sizeof(dcdn_buf)); | ||
+ RTE_LOG(DEBUG, IPVS, "get dcdn toa addr %s\n", dcdn_buf); | ||
+#endif | ||
+ } | ||
tcp_in_add_toa(conn, mbuf, th); | ||
} | ||
|
||
-- | ||
1.8.3.1 | ||
|