Hi Jeremy,
> Is there any documentation available for the libipvs interface? I'm
wanting
> to add/remove realservers from the ipvs table and change the server
weights.
>
> If not, I'll just look at how it's done in ipvsadm.
Here is a quick example on howto use libipvs (the code is taken from
Keepalived: ipvswrapper.c):
[Pseudo code is used]
1. For conventional use define a ipvs_talk function as follow :
=> This function is responsible of sending request to IPVS kernel code
using libipvs interface.
=> cmd is the command type and can take the following value (ipvs syncd
excluded from the list) :
o IP_VS_SO_SET_ADD
o IP_VS_SO_SET_DEL
o IP_VS_SO_SET_ADDDEST
o IP_VS_SO_SET_DELDEST
=> I consider you are using IPVS for Kernel 2.4 series.
static int
ipvs_talk(int cmd, struct ip_vs_rule_user *urule)
{
int result;
/* Init IPVS kernel channel */
if (ipvs_init()) {
/* try to insmod the ip_vs module if ipvs_init failed */
if (modprobe_ipvs() || ipvs_init()) {
printf("IPVS : Can't initialize ipvs: %s\n",
ipvs_strerror(errno));
return IPVS_ERROR;
}
}
result = ipvs_command(cmd, urule);
if (result)
printf("IPVS : %s\n", ipvs_strerror(errno));
ipvs_close();
return IPVS_SUCCESS;
}
2. Define a IPVS rule creation function :
=> This function define IPVS urule that will be passed to ipvs_talk() func
=> cmd take the same values as ipvs_talk() cmd arg
=> Kernel 2.4 IPVS code is supposed used
int
ipvs_cmd(int cmd)
{
struct ip_vs_rule_user urule;
memset(&urule, 0, sizeof (struct ip_vs_rule_user));
strncpy(urule.sched_name, sched, IP_VS_SCHEDNAME_MAXLEN);
urule.weight = 1;
urule.conn_flags = loadbalancing_kind;
urule.netmask = ((u_int32_t) 0xffffffff);
urule.protocol = service_type;
if (!parse_timeout(timeout_persistence, &urule.timeout))
printf("IPVS: illegal timeout.\n");
if (urule.timeout != 0 || granularity_persistence)
urule.vs_flags = IP_VS_SVC_F_PERSISTENT;
/* VS specific */
if (fwmark) {
urule.vfwmark = fwmark;
} else {
urule.vaddr = vs_addr;
urule.vport = vs_port;
}
if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
if (granularity_persistence)
urule.netmask = granularity_persistence;
/* SVR specific */
if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST) {
urule.weight = weight;
urule.daddr = rs_addr;
urule.dport = rs_port;
}
/* Talk to the IPVS channel */
return ipvs_talk(cmd, &urule);
}
The values used here are :
o sched : Load balancing scheduler
- Type : char *
- Values : rr, wrr, lc, wlc, lblc, dh, sh
o loadbalancing_kind : Routing method
- Type : char *
- Values : NAT, DR, TUN
o service_type : Virtual service type
- Type : uint16_t
- Value : IPPROTO_TCP, IPPROTO_UDP
o timeout_persistence : Timeout for persistent virtual services definition
- Type : char[5]
- Value : integer string
o granularity_persistence : Persistence Granularity
- Type : uint32_t
- Value : inet_addr() 32 bit network representation
o fwmark : Virtual Service is a firewall mark
- Type : int
- Value : integer
o vs_addr & vs_port : Virtual service definition
- Type : vs_addr = uint32_t , vs_port = uint16_t
- Value : vs_addr is a network representation 32bit of IP address of
the virtual service
o rs_addr & rs_port : Real service definition (the same as vs_addr &
vs_port definition)
o weight : Real service weight definition
- Type : int
- Value : integer
=> modprobe_ipvs(...) & parse_timeout(...) funcs are coming from ipvsadm.c
code.
The description bellow is very short, for more information on other
option/definition (ipvs syncd manipulation) please look into ipvsadm code.
Best regards,
Alexandre
|