Skip to content

Commit

Permalink
ipvs: support proxy protocol config
Browse files Browse the repository at this point in the history
Signed-off-by: ywc689 <ywc689@163.com>
  • Loading branch information
ywc689 committed Dec 8, 2023
1 parent 121e990 commit 28397f4
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 12 deletions.
38 changes: 32 additions & 6 deletions include/conf/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
#define DEST_INHIBIT_DURATION_MIN 5 // 5s
#define DEST_INHIBIT_DURATION_MAX 3600 // 1h

enum {
PROXY_PROTOCOL_DISABLE = 0,
PROXY_PROTOCOL_V1,
PROXY_PROTOCOL_V2,
};

struct dest_check_configs {
uint8_t types; // DEST_HC_*

Expand All @@ -76,16 +82,17 @@ struct dest_check_configs {
typedef struct dp_vs_service_compat {
/*base*/
int af;
uint16_t proto;
uint8_t proto;
uint8_t proxy_protocol; /* proxy protocol version: DISABLE | V1 | V2 */
uint16_t port;
uint32_t fwmark; /* firwall mark of service */
unsigned flags; /* virtual service flags */
unsigned timeout; /* persistent timeout in sec */
uint32_t fwmark; /* firwall mark of service */
unsigned flags; /* virtual service flags */
unsigned timeout; /* persistent timeout in sec */
unsigned conn_timeout;
uint32_t netmask; /* persistent netmask */
uint32_t netmask; /* persistent netmask */
unsigned bps;
unsigned limit_proportion;
union inet_addr addr; /* virtual ip address */
union inet_addr addr; /* virtual ip address */
char sched_name[DP_VS_SCHEDNAME_MAXLEN];

/*dp_vs_service_user & dp_vs_service_entry*/
Expand Down Expand Up @@ -170,5 +177,24 @@ dest_check_configs_sanity(struct dest_check_configs *conf) {
return res;
};

static inline uint8_t proxy_protocol_type(const char *str) {
if (!strcasecmp(str, "v1"))
return PROXY_PROTOCOL_V1;
if (!strcasecmp(str, "v2"))
return PROXY_PROTOCOL_V2;
return PROXY_PROTOCOL_DISABLE;
}

static inline const char *proxy_protocol_str(uint8_t type) {
switch (type) {
case PROXY_PROTOCOL_DISABLE:
return "disable";
case PROXY_PROTOCOL_V1:
return "v1";
case PROXY_PROTOCOL_V2:
return "v2";
}
return "unknown";
}

#endif /* __DPVS_SVC_CONF_H__ */
3 changes: 3 additions & 0 deletions include/ipvs/conn.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ struct dp_vs_conn {
uint32_t last_ack_seq; /* ack seq of the last ack packet */
rte_atomic32_t dup_ack_cnt; /* count of repeated ack packets */

uint8_t pp_version; /* proxy protocol version */
uint8_t pp_sent; /* proxy protocol data has sent, for udp only */

/* flags and state transition */
volatile uint16_t flags;
volatile uint16_t state;
Expand Down
3 changes: 2 additions & 1 deletion include/ipvs/service.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ struct dp_vs_service {
*/
int af;
uint8_t proto; /* TCP/UDP/... */
union inet_addr addr; /* virtual IP address */
uint8_t proxy_protocol;
uint16_t port;
uint32_t fwmark;
union inet_addr addr; /* virtual IP address */
struct dp_vs_match *match;

unsigned flags;
Expand Down
7 changes: 5 additions & 2 deletions src/ipvs/ip_vs_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,9 +468,10 @@ static int dp_vs_service_add(struct dp_vs_service_conf *u,

svc->af = u->af;
svc->proto = u->proto;
svc->addr = u->addr;
svc->proxy_protocol = u->proxy_protocol;
svc->port = u->port;
svc->fwmark = u->fwmark;
svc->addr = u->addr;
svc->flags = u->flags;
svc->timeout = u->timeout;
svc->conn_timeout = u->conn_timeout;
Expand Down Expand Up @@ -549,6 +550,7 @@ static int dp_vs_service_edit(struct dp_vs_service *svc, struct dp_vs_service_co
svc->flags = u->flags | DP_VS_SVC_F_HASHED;
svc->timeout = u->timeout;
svc->conn_timeout = u->conn_timeout;
svc->proxy_protocol = u->proxy_protocol;
svc->netmask = u->netmask;
svc->bps = u->bps;
svc->limit_proportion = u->limit_proportion;
Expand Down Expand Up @@ -645,9 +647,10 @@ dp_vs_service_copy(struct dp_vs_service_entry *dst, struct dp_vs_service *src)
memset(dst, 0, sizeof(*dst));
dst->af = src->af;
dst->proto = src->proto;
dst->addr = src->addr;
dst->proxy_protocol = src->proxy_protocol;
dst->port = src->port;
dst->fwmark = src->fwmark;
dst->addr = src->addr;
snprintf(dst->sched_name, sizeof(dst->sched_name),
"%s", src->scheduler->name);
dst->flags = src->flags;
Expand Down
10 changes: 10 additions & 0 deletions tools/ipvsadm/ipvsadm.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ enum {
TAG_CONN_EXPIRE_QUIESCENT,
TAG_DEST_CHECK,
TAG_CONN_TIMEOUT,
TAG_PROXY_PROTOCOL,
};

/* various parsing helpers & parsing functions */
Expand Down Expand Up @@ -560,6 +561,7 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
{ "expire-quiescent", '\0', POPT_ARG_NONE, NULL, TAG_CONN_EXPIRE_QUIESCENT, NULL, NULL },
{ "dest-check", '\0', POPT_ARG_STRING, &optarg, TAG_DEST_CHECK, NULL, NULL},
{ "conn-timeout", '\0', POPT_ARG_INT, &intarg, TAG_CONN_TIMEOUT, NULL, NULL},
{ "proxy-protocol", '\0', POPT_ARG_STRING, &optarg, TAG_PROXY_PROTOCOL, NULL, NULL},
{ NULL, 0, 0, NULL, 0, NULL, NULL }
};

Expand Down Expand Up @@ -978,6 +980,11 @@ parse_options(int argc, char **argv, struct ipvs_command_entry *ce,
ce->dpvs_svc.conn_timeout = intarg;
break;
}
case TAG_PROXY_PROTOCOL:
{
ce->dpvs_svc.proxy_protocol = proxy_protocol_type(optarg);
break;
}
default:
fail(2, "invalid option `%s'",
poptBadOption(context, POPT_BADOPTION_NOALIAS));
Expand Down Expand Up @@ -1702,6 +1709,7 @@ static void usage_exit(const char *program, const int exit_status)
" --connection -c output of current IPVS connections\n"
" --timeout output of timeout (tcp tcpfin udp)\n"
" --conn-timeout set connection established timeout\n"
" --proxy-protocol proxy protocol config (disable|v1|v2)\n"
" --daemon output of daemon information\n"
" --stats output of statistics information\n"
" --rate output of rate information\n"
Expand Down Expand Up @@ -2163,6 +2171,8 @@ print_service_entry(dpvs_service_compat_t *se, unsigned int format)
printf(" synproxy");
if (se->conn_timeout != 0)
printf(" conn-timeout %u", se->conn_timeout);
if (se->proxy_protocol != PROXY_PROTOCOL_DISABLE)
printf(" pp%s", proxy_protocol_str(se->proxy_protocol));
if (se->flags & IP_VS_SVC_F_EXPIRE_QUIESCENT)
printf(" expire-quiescent");
if (se->check_conf.types) {
Expand Down
1 change: 1 addition & 0 deletions tools/keepalived/keepalived/check/check_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ alloc_vs(const char *param1, const char *param2)
#endif
}

new->proxy_protocol = PROXY_PROTOCOL_DISABLE;
new->virtualhost = NULL;
new->alpha = false;
new->omega = false;
Expand Down
12 changes: 10 additions & 2 deletions tools/keepalived/keepalived/check/check_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,8 +1056,8 @@ static void
limit_proportion_handler(const vector_t *strvec)
{
virtual_server_t *vs = LIST_TAIL_DATA(check_data->vs);
char *str = vector_slot(strvec, 1);
vs->limit_proportion = atoi(str);
char *str = vector_slot(strvec, 1);
vs->limit_proportion = atoi(str);
}

static void
Expand All @@ -1073,6 +1073,13 @@ establish_timeout_handler(const vector_t *strvec)
vs->conn_timeout = conn_timeout;
}

static void
proxy_protocol_handler(const vector_t *strvec)
{
virtual_server_t *vs = LIST_TAIL_DATA(check_data->vs);
vs->proxy_protocol = proxy_protocol_type((const char *)vector_slot(strvec, 1));
}

static void
src_range_handler(const vector_t *strvec)
{
Expand Down Expand Up @@ -1173,6 +1180,7 @@ init_check_keywords(bool active)
#endif
install_keyword("lb_kind", &forwarding_handler);
install_keyword("establish_timeout", &establish_timeout_handler);
install_keyword("proxy_protocol", &proxy_protocol_handler);
install_keyword("lvs_method", &forwarding_handler);
#ifdef _HAVE_PE_NAME_
install_keyword("persistence_engine", &pengine_handler);
Expand Down
1 change: 1 addition & 0 deletions tools/keepalived/keepalived/check/ipvswrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,7 @@ static void ipvs_set_srule(int cmd, dpvs_service_compat_t *srule, virtual_server
srule->flags = vs->flags;
srule->netmask = (vs->af == AF_INET6) ? 128 : ((uint32_t) 0xffffffff);
srule->proto = vs->service_type;
srule->proxy_protocol = vs->proxy_protocol;
srule->bps = vs->bps;
srule->limit_proportion = vs->limit_proportion;
srule->conn_timeout = vs->conn_timeout;
Expand Down
1 change: 1 addition & 0 deletions tools/keepalived/keepalived/check/ipwrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1378,6 +1378,7 @@ clear_diff_services(list old_checkers_queue)
because the VS still exists in new configuration */
if (strcmp(vs->sched, new_vs->sched) ||
vs->flags != new_vs->flags ||
vs->proxy_protocol != new_vs->proxy_protocol ||
vs->persistence_granularity != new_vs->persistence_granularity ||
vs->persistence_timeout != new_vs->persistence_timeout ||
vs->conn_timeout != new_vs->conn_timeout ||
Expand Down
1 change: 1 addition & 0 deletions tools/keepalived/keepalived/check/libipvs.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ int dpvs_update_service_by_options(dpvs_service_compat_t *svc, unsigned int opti
entry.timeout = svc->timeout;
}
entry.conn_timeout = svc->conn_timeout;
entry.proxy_protocol = svc->proxy_protocol;

if (options & OPT_NETMASK) {
entry.netmask = svc->netmask;
Expand Down
4 changes: 3 additions & 1 deletion tools/keepalived/keepalived/include/check_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ typedef struct _virtual_server {
uint32_t vfwmark;
real_server_t *s_svr;
uint16_t af;
uint16_t service_type;
uint8_t service_type;
uint8_t proxy_protocol;
bool ha_suspend;
int ha_suspend_addr_count;
#ifdef _WITH_LVS_
Expand Down Expand Up @@ -298,6 +299,7 @@ static inline bool quorum_equal(const notify_script_t *quorum1,
#define VS_ISEQ(X,Y) (sockstorage_equal(&(X)->addr,&(Y)->addr) &&\
(X)->vfwmark == (Y)->vfwmark &&\
(X)->service_type == (Y)->service_type &&\
(X)->proxy_protocol == (Y)->proxy_protocol &&\
(X)->forwarding_method == (Y)->forwarding_method &&\
(X)->hash_target == (Y)->hash_target &&\
(X)->syn_proxy == (Y)->syn_proxy &&\
Expand Down

0 comments on commit 28397f4

Please sign in to comment.