convert kmeans_incr threshold
[actl.git] / parse.y
blob34e05be8c27baa059e9cd8f9f36845b5d6bce01f
1 /*
2 * Copyright (c) 2016 Mohamed Aslan <maslan@sce.carleton.ca>
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <stdarg.h>
21 #include <string.h>
22 #include <err.h>
23 #include <errno.h>
24 #include <sys/queue.h>
25 #include <arpa/inet.h>
27 #include "conf.h"
28 #include "utils.h"
30 /* types */
31 SIMPLEQ_HEAD(list, list_item);
32 struct list_item {
33 void *val;
34 SIMPLEQ_ENTRY(list_item) next;
37 /* lex vars */
38 extern FILE *yyin;
39 extern int yylineno;
40 extern int yylex(void);
41 /* global vars */
42 int yyerror(const char *, ...);
43 static ofp_fptr check_ofp_version(const char *);
44 static char *filename;
45 static struct config *conf;
48 %union {
49 int i;
50 char *s;
51 struct list *l;
54 %token ID
55 %token LISTEN ON
56 %token PEERS CONTROLLER
57 %token IP PORT
58 %token REPLICAS
59 %token OPENFLOW VERSION
60 %token APPLICATION
61 %token ADAPT EVERY SEC MIN
62 %token LEARN USING WITH FOR EQUAL
63 %token KMEANSSEQ CLUSTERS
64 %token KMEANSINCR THRESHOLD
65 %token LOG TO
66 %token TOPOLOGY HOST AT DPID
67 %token COMMA LCBRACKET RCBRACKET
69 %token<i> BOOL
70 %token<i> NUMBER
71 %token<s> VAR
72 %token<s> STRING
74 %type<l> peer_list
75 %type<l> str_list
76 %type<l> param_list
77 %type<l> host_list
81 main :
82 | main id
83 | main listen
84 | main peers
85 | main replicas
86 | main openflow
87 | main application
88 | main adapt
89 | main learn
90 | main log
91 | main topology
94 id : ID STRING {
95 conf->c_nodeid = strdup($2);
99 listen : LISTEN ON PORT NUMBER {
100 conf->c_co_port = $4;
104 peer_list : CONTROLLER STRING IP STRING PORT NUMBER {
105 struct peer *p = (struct peer *)malloc(sizeof(struct peer));
106 struct list_item *q = (struct list_item *)malloc(sizeof(struct list_item));
108 p->node_id = strdup($2);
109 if (!inet_aton($4, &p->ip_addr))
110 errx(1, "invalid IP address");
111 p->port = $6;
113 q->val = p;
114 $$ = (struct list *)malloc(sizeof(struct list));
115 SIMPLEQ_INIT($$);
116 SIMPLEQ_INSERT_TAIL($$, q, next);
118 | peer_list COMMA CONTROLLER STRING IP STRING PORT NUMBER {
119 struct peer *p = (struct peer *)malloc(sizeof(struct peer));
120 struct list_item *q = (struct list_item *)malloc(sizeof(struct list_item));
122 p->node_id = strdup($4);
123 if (!inet_aton($6, &p->ip_addr))
124 errx(1, "invalid IP address");
125 p->port = $8;
127 q->val = p;
128 SIMPLEQ_INSERT_TAIL($1, q, next);
132 peers : PEERS LCBRACKET peer_list RCBRACKET {
133 int i = 0, n = 0;
134 struct list_item *p;
136 SIMPLEQ_FOREACH(p, $3, next)
137 ++n;
138 conf->c_npeers = n;
139 conf->c_peers = (struct peer *)reallocarray(NULL, n, sizeof(struct peer));
140 while (!SIMPLEQ_EMPTY($3)) {
141 p = SIMPLEQ_FIRST($3);
142 conf->c_peers[i++] = *((struct peer *)p->val);
143 SIMPLEQ_REMOVE_HEAD($3, next);
144 free(p);
146 free($3);
150 replicas : REPLICAS NUMBER {
151 conf->c_nreplicas = $2;
155 openflow : OPENFLOW VERSION STRING {
156 if ((conf->c_ofp = check_ofp_version($3)) == NULL) {
157 yyerror("OpenFlow version '%s' not supported.", $3);
158 YYABORT;
160 conf->c_ofp_verstr = strdup($3);
162 | OPENFLOW LISTEN ON PORT NUMBER {
163 conf->c_sw_port = $5;
167 str_list : STRING {
168 struct list_item *s = (struct list_item *)malloc(sizeof(struct list_item));
170 s->val = strdup($1);
171 $$ = (struct list *)malloc(sizeof(struct list));
172 SIMPLEQ_INIT($$);
173 SIMPLEQ_INSERT_TAIL($$, s, next);
175 | str_list COMMA STRING {
176 struct list_item *s = (struct list_item *)malloc(sizeof(struct list_item));
178 s->val = strdup($3);
179 SIMPLEQ_INSERT_TAIL($1, s, next);
183 param_list : VAR STRING {
184 struct list_item *p, *q;
186 p = (struct list_item *)malloc(sizeof(struct list_item));
187 q = (struct list_item *)malloc(sizeof(struct list_item));
188 asprintf((char **)&p->val, "--%s", $1);
189 q->val = strdup($2);
190 $$ = (struct list *)malloc(sizeof(struct list));
191 SIMPLEQ_INIT($$);
192 SIMPLEQ_INSERT_TAIL($$, p, next);
193 SIMPLEQ_INSERT_TAIL($$, q, next);
195 | param_list COMMA VAR STRING {
196 struct list_item *p, *q;
198 p = (struct list_item *)malloc(sizeof(struct list_item));
199 q = (struct list_item *)malloc(sizeof(struct list_item));
200 asprintf((char **)&p->val, "--%s", $3);
201 q->val = strdup($4);
202 SIMPLEQ_INSERT_TAIL($1, p, next);
203 SIMPLEQ_INSERT_TAIL($1, q, next);
205 | param_list COMMA VAR LCBRACKET str_list RCBRACKET {
206 struct list_item *p, *q;
208 while (!SIMPLEQ_EMPTY($5)) {
209 p = (struct list_item *)malloc(sizeof(struct list_item));
210 asprintf((char **)&p->val, "--%s", $3);
211 SIMPLEQ_INSERT_TAIL($1, p, next);
212 q = SIMPLEQ_FIRST($5);
213 SIMPLEQ_REMOVE_HEAD($5, next);
214 SIMPLEQ_INSERT_TAIL($1, q, next);
219 application : APPLICATION STRING {
220 conf->c_app_name = strdup($2);
222 | APPLICATION STRING LCBRACKET param_list RCBRACKET {
223 int i = 0;
224 int argc = 0;
225 char **argv;
226 struct list_item *p;
228 conf->c_app_name = strdup($2);
229 SIMPLEQ_FOREACH(p, $4, next)
230 ++argc;
231 ++argc;
232 argv = (char **)reallocarray(NULL, argc, sizeof(char *));
233 argv[0] = strdup($2);
234 while (!SIMPLEQ_EMPTY($4)) {
235 p = SIMPLEQ_FIRST($4);
236 argv[++i] = (char *)p->val;
237 SIMPLEQ_REMOVE_HEAD($4, next);
238 free(p);
240 conf->c_app_argc = argc;
241 conf->c_app_argv = argv;
242 free($4);
246 adapt : ADAPT EVERY NUMBER SEC {
247 if ($3 < 1) {
248 yyerror("adaptation time must be > 1.");
249 YYABORT;
251 conf->c_atime = $3;
253 | ADAPT EVERY NUMBER MIN {
254 if ($3 < 1) {
255 yyerror("adaptation time must be > 1.");
256 YYABORT;
258 conf->c_atime = $3 * 60;
262 learn : LEARN USING KMEANSSEQ WITH CLUSTERS EQUAL NUMBER FOR NUMBER SEC {
263 if ($9 < 30) {
264 yyerror("learning time must be >= 30 sec.");
265 YYABORT;
267 conf->c_ltime = $9;
268 conf->c_lalgo = LEARN_KMEANS_SEQ;
269 conf->c_lparam = $7;
271 | LEARN USING KMEANSSEQ WITH CLUSTERS EQUAL NUMBER FOR NUMBER MIN {
272 if ($9 < 1) {
273 yyerror("use you may use seconds for learning time.");
274 YYABORT;
276 conf->c_ltime = $9 * 60;
277 conf->c_lalgo = LEARN_KMEANS_SEQ;
278 conf->c_lparam = $7;
280 | LEARN USING KMEANSINCR WITH THRESHOLD EQUAL NUMBER FOR NUMBER SEC {
281 if ($9 < 30) {
282 yyerror("learning time must be >= 30 sec.");
283 YYABORT;
285 conf->c_ltime = $9;
286 conf->c_lalgo = LEARN_KMEANS_INCR;
287 conf->c_lparam = $7;
289 | LEARN USING KMEANSINCR WITH THRESHOLD EQUAL NUMBER FOR NUMBER MIN {
290 if ($9 < 1) {
291 yyerror("use you may use seconds for learning time.");
292 YYABORT;
294 conf->c_ltime = $9 * 60;
295 conf->c_lalgo = LEARN_KMEANS_INCR;
296 conf->c_lparam = $7;
300 log : LOG TO STRING {
301 conf->c_logfile = strdup($3);
305 host_list : HOST STRING AT DPID STRING PORT NUMBER {
306 struct host_info *h = (struct host_info *)malloc(sizeof(struct host_info));
307 struct list_item *p = (struct list_item *)malloc(sizeof(struct list_item));
309 if (!inet_aton($2, &h->ip_addr))
310 errx(1, "invalid IP address");
311 if (!(h->dpid = dpid_aton($5)))
312 errx(1, "invalid DPID");
313 h->port = $7;
315 p->val = h;
316 $$ = (struct list *)malloc(sizeof(struct list));
317 SIMPLEQ_INIT($$);
318 SIMPLEQ_INSERT_TAIL($$, p, next);
320 | host_list COMMA HOST STRING AT DPID STRING PORT NUMBER {
321 struct host_info *h = (struct host_info *)malloc(sizeof(struct host_info));
322 struct list_item *p = (struct list_item *)malloc(sizeof(struct list_item));
324 if (!inet_aton($4, &h->ip_addr))
325 errx(1, "invalid IP address");
326 if (!(h->dpid = dpid_aton($7)))
327 errx(1, "invalid DPID");
328 h->port = $9;
330 p->val = h;
331 SIMPLEQ_INSERT_TAIL($1, p, next);
335 topology : TOPOLOGY LCBRACKET host_list RCBRACKET {
336 int i = 0, n = 0;
337 struct host_info **hosts;
338 struct list_item *p;
340 SIMPLEQ_FOREACH(p, $3, next)
341 ++n;
342 hosts = (struct host_info **)reallocarray(NULL, n, sizeof(struct host_info *));
343 while (!SIMPLEQ_EMPTY($3)) {
344 p = SIMPLEQ_FIRST($3);
345 hosts[i++] = (struct host_info *)p->val;
346 SIMPLEQ_REMOVE_HEAD($3, next);
347 free(p);
349 conf->c_topo_n = n;
350 conf->c_topo = hosts;
351 free($3);
356 static ofp_fptr
357 check_ofp_version(const char *ver)
359 int i;
361 for (i = 0 ; i < N_OFP_VERS ; i++)
362 if (!strcmp(ver, ofp_vers[i].ver))
363 return ofp_vers[i].func;
364 return NULL;
368 yyerror(const char *fmt, ...)
370 va_list ap;
372 va_start(ap, fmt);
373 fprintf(stdout, "%s:%d: ", filename, yylineno);
374 vfprintf(stdout, fmt, ap);
375 fprintf(stdout, "\n");
376 va_end(ap);
378 return 0;
382 parse_config(struct config *c, const char *file)
384 int ret;
386 if (c == NULL)
387 errx(1, "parse_config");
388 if ((yyin = fopen(file, "r")) == NULL) {
389 errx(1, "failed to load config file");
391 filename = strdup(file);
392 conf = c;
393 conf->c_app_name = NULL;
394 conf->c_logfile = NULL;
395 ret = yyparse();
396 fclose(yyin);
398 return ret;