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.
24 #include <sys/queue.h>
25 #include <arpa/inet.h>
31 SIMPLEQ_HEAD
(list
, list_item
);
34 SIMPLEQ_ENTRY
(list_item
) next
;
40 extern
int yylex(void);
42 int yyerror(const char *, ...
);
43 static ofp_fptr check_ofp_version
(const char *);
44 static char *filename
;
45 static struct config
*conf
;
60 %token OPENFLOW VERSION
62 %token ADAPT EVERY SEC MIN
65 %token TOPOLOGY HOST AT DPID
66 %token COMMA LCBRACKET RCBRACKET
93 conf
->c_nodeid
= strdup
($2);
97 listen
: LISTEN ON PORT NUMBER
{
102 controller
: CONTROLLER STRING IP STRING PORT NUMBER
{
103 //printf("CONTROLLER: %s, ip addr=%s, port=%d\n", $2, $4, $6);
105 | CONTROLLER STRING IP STRING
{
106 //printf("CONTROLLER: %s, ip addr=%s\n", $2, $4);
110 replicas
: REPLICAS NUMBER
{
111 conf
->c_nreplicas
= $2;
115 openflow
: OPENFLOW VERSION STRING
{
116 if
((conf
->c_ofp
= check_ofp_version
($3)) == NULL
) {
117 yyerror("OpenFlow version '%s' not supported.", $3);
120 conf
->c_ofp_verstr
= strdup
($3);
122 | OPENFLOW LISTEN ON PORT NUMBER
{
123 conf
->c_sw_port
= $5;
128 struct list_item
*s
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
132 SIMPLEQ_INSERT_TAIL
($$
, s
, next
);
134 | str_list COMMA STRING
{
135 struct list_item
*s
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
138 SIMPLEQ_INSERT_TAIL
($1, s
, next
);
142 param_list
: VAR STRING
{
143 struct list_item
*p
, *q
;
145 p
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
146 q
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
147 asprintf
((char **)&p
->val
, "--%s", $1);
150 SIMPLEQ_INSERT_TAIL
($$
, p
, next
);
151 SIMPLEQ_INSERT_TAIL
($$
, q
, next
);
153 | param_list COMMA VAR STRING
{
154 struct list_item
*p
, *q
;
156 p
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
157 q
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
158 asprintf
((char **)&p
->val
, "--%s", $3);
160 SIMPLEQ_INSERT_TAIL
($1, p
, next
);
161 SIMPLEQ_INSERT_TAIL
($1, q
, next
);
163 | param_list COMMA VAR LCBRACKET str_list RCBRACKET
{
164 struct list_item
*p
, *q
;
166 while
(!SIMPLEQ_EMPTY
($5)) {
167 p
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
168 asprintf
((char **)&p
->val
, "--%s", $3);
169 SIMPLEQ_INSERT_TAIL
($1, p
, next
);
170 q
= SIMPLEQ_FIRST
($5);
171 SIMPLEQ_REMOVE_HEAD
($5, next
);
172 SIMPLEQ_INSERT_TAIL
($1, q
, next
);
177 application
: APPLICATION STRING
{
178 conf
->c_app_name
= strdup
($2);
180 | APPLICATION STRING LCBRACKET param_list RCBRACKET
{
186 conf
->c_app_name
= strdup
($2);
187 SIMPLEQ_FOREACH
(p
, $4, next
)
190 argv
= (char **)reallocarray
(NULL
, argc
, sizeof
(char *));
191 argv
[0] = strdup
($2);
192 while
(!SIMPLEQ_EMPTY
($4)) {
193 p
= SIMPLEQ_FIRST
($4);
195 SIMPLEQ_REMOVE_HEAD
($4, next
);
198 conf
->c_app_argc
= argc
;
199 conf
->c_app_argv
= argv
;
203 adapt
: ADAPT EVERY NUMBER SEC
{
205 yyerror("adaptation time must be > 1.");
210 | ADAPT EVERY NUMBER MIN
{
212 yyerror("adaptation time must be > 1.");
215 conf
->c_atime
= $3 * 60;
219 learn
: LEARN FOR NUMBER SEC
{
221 yyerror("learning time must be >= 30 sec.");
226 | LEARN FOR NUMBER MIN
{
228 yyerror("use you may use seconds for learning time.");
231 conf
->c_ltime
= $3 * 60;
235 log
: LOG TO STRING
{
236 conf
->c_logfile
= strdup
($3);
240 host_list
: HOST STRING AT DPID STRING PORT NUMBER
{
241 struct host_info
*h
= (struct host_info
*)malloc
(sizeof
(struct host_info
));
242 struct list_item
*p
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
244 if
(!inet_aton
($2, &h
->ip_addr
))
245 errx
(1, "invalid IP address");
246 if
(!(h
->dpid
= dpid_aton
($5)))
247 errx
(1, "invalid DPID");
252 SIMPLEQ_INSERT_TAIL
($$
, p
, next
);
254 | host_list COMMA HOST STRING AT DPID STRING PORT NUMBER
{
255 struct host_info
*h
= (struct host_info
*)malloc
(sizeof
(struct host_info
));
256 struct list_item
*p
= (struct list_item
*)malloc
(sizeof
(struct list_item
));
258 if
(!inet_aton
($4, &h
->ip_addr
))
259 errx
(1, "invalid IP address");
260 if
(!(h
->dpid
= dpid_aton
($7)))
261 errx
(1, "invalid DPID");
265 SIMPLEQ_INSERT_TAIL
($1, p
, next
);
269 topology
: TOPOLOGY LCBRACKET host_list RCBRACKET
{
271 struct host_info
**hosts
;
274 SIMPLEQ_FOREACH
(p
, $3, next
)
276 hosts
= (struct host_info
**)reallocarray
(NULL
, n
, sizeof
(struct host_info
*));
277 while
(!SIMPLEQ_EMPTY
($3)) {
278 p
= SIMPLEQ_FIRST
($3);
279 hosts
[i
++] = (struct host_info
*)p
->val
;
280 SIMPLEQ_REMOVE_HEAD
($3, next
);
284 conf
->c_topo
= hosts
;
290 check_ofp_version
(const char *ver
)
294 for
(i
= 0 ; i
< N_OFP_VERS
; i
++)
295 if
(!strcmp
(ver
, ofp_vers
[i
].ver
))
296 return ofp_vers
[i
].func
;
301 yyerror(const char *fmt
, ...
)
306 fprintf
(stdout
, "%s:%d: ", filename
, yylineno
);
307 vfprintf
(stdout
, fmt
, ap
);
308 fprintf
(stdout
, "\n");
315 parse_config
(struct config
*c
, const char *file
)
320 errx
(1, "parse_config");
321 if
((yyin
= fopen
(file
, "r")) == NULL
) {
322 errx
(1, "failed to load config file");
324 filename
= strdup
(file
);
326 conf
->c_app_name
= NULL
;
327 conf
->c_logfile
= NULL
;