Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON load balancer config file #328

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
122 changes: 96 additions & 26 deletions examples/load_balancer/load_balancer.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
#include "onvm_flow_table.h"
#include "onvm_nflib.h"
#include "onvm_pkt_helper.h"
#include "onvm_config_common.h"


#include "cJSON.h"
andreaseno marked this conversation as resolved.
Show resolved Hide resolved

#define NF_TAG "load_balancer"
#define TABLE_SIZE 65536
Expand All @@ -95,6 +99,13 @@ struct loadbalance {

/* config file */
char *cfg_filename;

/* LB policy */
char *policy;

/* structures to store server weights */
int *weights;
int total_weight;
};

/* Struct for backend servers */
Expand Down Expand Up @@ -240,49 +251,83 @@ parse_app_args(int argc, char *argv[], const char *progname) {
/*
* This function parses the backend config. It takes the filename
* and fills up the backend_server array. This includes the mac and ip
* address of the backend servers
* address of the backend servers as well as their weights
*/
static int
parse_backend_config(void) {
int ret, temp, i;
char ip[32];
char mac[32];
FILE *cfg;
parse_backend_json_config(void) {
int ret, i;
i = 0;

cfg = fopen(lb->cfg_filename, "r");
if (cfg == NULL) {
rte_exit(EXIT_FAILURE, "Error openning server \'%s\' config\n", lb->cfg_filename);
cJSON *config_json = onvm_config_parse_file(lb->cfg_filename);
cJSON *list_size = NULL;
cJSON *policy = NULL;
cJSON *ip_addr = NULL;
cJSON *mac_addr = NULL;
cJSON *weight = NULL;

if (config_json == NULL) {
rte_exit(EXIT_FAILURE, "%s file could not be parsed/not found. Assure config file"
" the directory to the config file is being specified.\n", lb->cfg_filename);
andreaseno marked this conversation as resolved.
Show resolved Hide resolved
}
ret = fscanf(cfg, "%*s %d", &temp);
if (temp <= 0) {
rte_exit(EXIT_FAILURE, "Error parsing config, need at least one server configurations\n");

config_json = config_json -> child;

list_size = cJSON_GetObjectItem(config_json, "LIST_SIZE");
policy = cJSON_GetObjectItem(config_json, "policy");

if (list_size == NULL) rte_exit(EXIT_FAILURE, "LIST_SIZE not found/invalid\n");
if (policy == NULL) rte_exit(EXIT_FAILURE, "Policy not found/invalid\n");

lb->server_count = list_size->valueint;
lb->policy = strdup(policy->valuestring);

if (!((!strcmp(lb->policy,"random")) || (!strcmp(lb->policy,"rrobin")) || (!strcmp(lb->policy,"weighted_random")))) {
rte_exit(EXIT_FAILURE, "Invalid policy. Check server.conf\n");
}
lb->server_count = temp;


lb->weights = (int*)calloc(lb->server_count,sizeof(int));
andreaseno marked this conversation as resolved.
Show resolved Hide resolved

lb->server = (struct backend_server *)rte_malloc("backend server info",
sizeof(struct backend_server) * lb->server_count, 0);
if (lb->server == NULL) {
rte_exit(EXIT_FAILURE, "Malloc failed, can't allocate server information\n");
}

for (i = 0; i < lb->server_count; i++) {
ret = fscanf(cfg, "%s %s", ip, mac);
if (ret != 2) {
rte_exit(EXIT_FAILURE, "Invalid backend config structure\n");
}
config_json = config_json->next;


ret = onvm_pkt_parse_ip(ip, &lb->server[i].d_ip);
while (config_json != NULL) {
andreaseno marked this conversation as resolved.
Show resolved Hide resolved
ip_addr = cJSON_GetObjectItem(config_json, "ip");
mac_addr = cJSON_GetObjectItem(config_json, "mac_addr");
weight = cJSON_GetObjectItem(config_json, "weight");

if (ip_addr == NULL) rte_exit(EXIT_FAILURE, "IP not found/invalid\n");
if (mac_addr == NULL) rte_exit(EXIT_FAILURE, "MAC address not found/invalid\n");
if (weight == NULL) rte_exit(EXIT_FAILURE, "Weight not found/invalid\n");
andreaseno marked this conversation as resolved.
Show resolved Hide resolved

ret = onvm_pkt_parse_ip(ip_addr->valuestring, &lb->server[i].d_ip);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Error parsing config IP address #%d\n", i);
}

ret = onvm_pkt_parse_mac(mac, lb->server[i].d_addr_bytes);
ret = onvm_pkt_parse_mac(mac_addr->valuestring, lb->server[i].d_addr_bytes);
if (ret < 0) {
rte_exit(EXIT_FAILURE, "Error parsing config MAC address #%d\n", i);
}

if (strcmp(lb->policy, "weighted_random")) lb->weights[i] = 1;
else {
lb->weights[i] = weight->valueint;
lb->total_weight += weight->valueint;
}
config_json = config_json->next;
i++;



}
cJSON_Delete(config_json);

fclose(cfg);
printf("\nARP config:\n");
for (i = 0; i < lb->server_count; i++) {
printf("%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8 " ", (lb->server[i].d_ip >> 24) & 0xFF,
Expand All @@ -293,7 +338,7 @@ parse_backend_config(void) {
lb->server[i].d_addr_bytes[5]);
}

return ret;
return ret;
andreaseno marked this conversation as resolved.
Show resolved Hide resolved
}

/*
Expand Down Expand Up @@ -460,10 +505,35 @@ table_add_entry(struct onvm_ft_ipv4_5tuple *key, struct flow_info **flow) {
}

lb->num_stored++;
data->dest = lb->num_stored % lb->server_count;
if (!strcmp(lb->policy,"random")) {
time_t t;
/* Intializes random number generator */
srand((unsigned) time(&t));
data->dest = rand() % lb->server_count;
}
else if (!strcmp(lb->policy,"rrobin")) {
data->dest = lb->num_stored % lb->server_count;
}
else if (!strcmp(lb->policy,"weighted_random")) {
time_t t;
int i, wrand, cur_weight_sum;
/* Intializes random number generator */
srand((unsigned) time(&t));
wrand = rand() % lb->total_weight;
cur_weight_sum=0;
for (i = 0; i < lb->server_count; i++) {
cur_weight_sum+=lb->weights[i];
if(wrand<=cur_weight_sum) {
data->dest=i;
break;
}
}

}


data->last_pkt_cycles = lb->elapsed_cycles;
data->is_active = 0;

*flow = data;

return 0;
Expand Down Expand Up @@ -636,7 +706,7 @@ main(int argc, char *argv[]) {
}

validate_iface_config();
parse_backend_config();
parse_backend_json_config();

lb->expire_time = 32;
lb->elapsed_cycles = rte_get_tsc_cycles();
Expand Down
3 changes: 0 additions & 3 deletions examples/load_balancer/server.conf

This file was deleted.

17 changes: 17 additions & 0 deletions examples/load_balancer/server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"Info" : {
"LIST_SIZE": 2,
"policy": "random"
andreaseno marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be all caps?

},
"Server0": {
"ip": "10.10.1.2",
"mac_addr": "90:e2:ba:ac:16:34",
"weight": 1
},
"Server1": {
"ip": "10.10.1.3",
"mac_addr": "90:e2:ba:b3:bb:7d",
"weight": 1
}

}
andreaseno marked this conversation as resolved.
Show resolved Hide resolved