meta-flow: New library for working with fields by id.
[sliver-openvswitch.git] / lib / ofp-parse.c
1 /*
2  * Copyright (c) 2010, 2011 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18
19 #include "ofp-parse.h"
20
21 #include <ctype.h>
22 #include <errno.h>
23 #include <stdlib.h>
24
25 #include "autopath.h"
26 #include "bundle.h"
27 #include "byte-order.h"
28 #include "dynamic-string.h"
29 #include "meta-flow.h"
30 #include "netdev.h"
31 #include "multipath.h"
32 #include "nx-match.h"
33 #include "ofp-util.h"
34 #include "ofpbuf.h"
35 #include "openflow/openflow.h"
36 #include "packets.h"
37 #include "socket-util.h"
38 #include "vconn.h"
39 #include "vlog.h"
40
41 VLOG_DEFINE_THIS_MODULE(ofp_parse);
42
43 static uint32_t
44 str_to_u32(const char *str)
45 {
46     char *tail;
47     uint32_t value;
48
49     if (!str[0]) {
50         ovs_fatal(0, "missing required numeric argument");
51     }
52
53     errno = 0;
54     value = strtoul(str, &tail, 0);
55     if (errno == EINVAL || errno == ERANGE || *tail) {
56         ovs_fatal(0, "invalid numeric format %s", str);
57     }
58     return value;
59 }
60
61 static uint64_t
62 str_to_u64(const char *str)
63 {
64     char *tail;
65     uint64_t value;
66
67     if (!str[0]) {
68         ovs_fatal(0, "missing required numeric argument");
69     }
70
71     errno = 0;
72     value = strtoull(str, &tail, 0);
73     if (errno == EINVAL || errno == ERANGE || *tail) {
74         ovs_fatal(0, "invalid numeric format %s", str);
75     }
76     return value;
77 }
78
79 static void
80 str_to_mac(const char *str, uint8_t mac[6])
81 {
82     if (sscanf(str, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))
83         != ETH_ADDR_SCAN_COUNT) {
84         ovs_fatal(0, "invalid mac address %s", str);
85     }
86 }
87
88 static void
89 str_to_ip(const char *str, ovs_be32 *ip)
90 {
91     struct in_addr in_addr;
92
93     if (lookup_ip(str, &in_addr)) {
94         ovs_fatal(0, "%s: could not convert to IP address", str);
95     }
96     *ip = in_addr.s_addr;
97 }
98
99 static struct ofp_action_output *
100 put_output_action(struct ofpbuf *b, uint16_t port)
101 {
102     struct ofp_action_output *oao;
103
104     oao = ofputil_put_OFPAT_OUTPUT(b);
105     oao->port = htons(port);
106     return oao;
107 }
108
109 static void
110 parse_enqueue(struct ofpbuf *b, char *arg)
111 {
112     char *sp = NULL;
113     char *port = strtok_r(arg, ":q", &sp);
114     char *queue = strtok_r(NULL, "", &sp);
115     struct ofp_action_enqueue *oae;
116
117     if (port == NULL || queue == NULL) {
118         ovs_fatal(0, "\"enqueue\" syntax is \"enqueue:PORT:QUEUE\"");
119     }
120
121     oae = ofputil_put_OFPAT_ENQUEUE(b);
122     oae->port = htons(str_to_u32(port));
123     oae->queue_id = htonl(str_to_u32(queue));
124 }
125
126 static void
127 parse_output(struct ofpbuf *b, char *arg)
128 {
129     if (strchr(arg, '[')) {
130         struct nx_action_output_reg *naor;
131         int ofs, n_bits;
132         uint32_t src;
133
134         nxm_parse_field_bits(arg, &src, &ofs, &n_bits);
135
136         naor = ofputil_put_NXAST_OUTPUT_REG(b);
137         naor->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits);
138         naor->src = htonl(src);
139         naor->max_len = htons(UINT16_MAX);
140     } else {
141         put_output_action(b, str_to_u32(arg));
142     }
143 }
144
145 static void
146 parse_resubmit(struct ofpbuf *b, char *arg)
147 {
148     struct nx_action_resubmit *nar;
149     char *in_port_s, *table_s;
150     uint16_t in_port;
151     uint8_t table;
152
153     in_port_s = strsep(&arg, ",");
154     if (in_port_s && in_port_s[0]) {
155         if (!ofputil_port_from_string(in_port_s, &in_port)) {
156             in_port = str_to_u32(in_port_s);
157         }
158     } else {
159         in_port = OFPP_IN_PORT;
160     }
161
162     table_s = strsep(&arg, ",");
163     table = table_s && table_s[0] ? str_to_u32(table_s) : 255;
164
165     if (in_port == OFPP_IN_PORT && table == 255) {
166         ovs_fatal(0, "at least one \"in_port\" or \"table\" must be specified "
167                   " on resubmit");
168     }
169
170     if (in_port != OFPP_IN_PORT && table == 255) {
171         nar = ofputil_put_NXAST_RESUBMIT(b);
172     } else {
173         nar = ofputil_put_NXAST_RESUBMIT_TABLE(b);
174         nar->table = table;
175     }
176     nar->in_port = htons(in_port);
177 }
178
179 static void
180 parse_set_tunnel(struct ofpbuf *b, const char *arg)
181 {
182     uint64_t tun_id = str_to_u64(arg);
183     if (tun_id > UINT32_MAX) {
184         ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(tun_id);
185     } else {
186         ofputil_put_NXAST_SET_TUNNEL(b)->tun_id = htonl(tun_id);
187     }
188 }
189
190 static void
191 parse_note(struct ofpbuf *b, const char *arg)
192 {
193     size_t start_ofs = b->size;
194     struct nx_action_note *nan;
195     int remainder;
196     size_t len;
197
198     nan = ofputil_put_NXAST_NOTE(b);
199
200     b->size -= sizeof nan->note;
201     while (*arg != '\0') {
202         uint8_t byte;
203         bool ok;
204
205         if (*arg == '.') {
206             arg++;
207         }
208         if (*arg == '\0') {
209             break;
210         }
211
212         byte = hexits_value(arg, 2, &ok);
213         if (!ok) {
214             ovs_fatal(0, "bad hex digit in `note' argument");
215         }
216         ofpbuf_put(b, &byte, 1);
217
218         arg += 2;
219     }
220
221     len = b->size - start_ofs;
222     remainder = len % OFP_ACTION_ALIGN;
223     if (remainder) {
224         ofpbuf_put_zeros(b, OFP_ACTION_ALIGN - remainder);
225     }
226     nan = (struct nx_action_note *)((char *)b->data + start_ofs);
227     nan->len = htons(b->size - start_ofs);
228 }
229
230 static void
231 parse_named_action(enum ofputil_action_code code, struct ofpbuf *b, char *arg)
232 {
233     struct ofp_action_dl_addr *oada;
234     struct ofp_action_vlan_pcp *oavp;
235     struct ofp_action_vlan_vid *oavv;
236     struct ofp_action_nw_addr *oana;
237     struct ofp_action_tp_port *oata;
238
239     switch (code) {
240     case OFPUTIL_OFPAT_OUTPUT:
241         parse_output(b, arg);
242         break;
243
244     case OFPUTIL_OFPAT_SET_VLAN_VID:
245         oavv = ofputil_put_OFPAT_SET_VLAN_VID(b);
246         oavv->vlan_vid = htons(str_to_u32(arg));
247         break;
248
249     case OFPUTIL_OFPAT_SET_VLAN_PCP:
250         oavp = ofputil_put_OFPAT_SET_VLAN_PCP(b);
251         oavp->vlan_pcp = str_to_u32(arg);
252         break;
253
254     case OFPUTIL_OFPAT_STRIP_VLAN:
255         ofputil_put_OFPAT_STRIP_VLAN(b);
256         break;
257
258     case OFPUTIL_OFPAT_SET_DL_SRC:
259     case OFPUTIL_OFPAT_SET_DL_DST:
260         oada = ofputil_put_action(code, b);
261         str_to_mac(arg, oada->dl_addr);
262         break;
263
264     case OFPUTIL_OFPAT_SET_NW_SRC:
265     case OFPUTIL_OFPAT_SET_NW_DST:
266         oana = ofputil_put_action(code, b);
267         str_to_ip(arg, &oana->nw_addr);
268         break;
269
270     case OFPUTIL_OFPAT_SET_NW_TOS:
271         ofputil_put_OFPAT_SET_NW_TOS(b)->nw_tos = str_to_u32(arg);
272         break;
273
274     case OFPUTIL_OFPAT_SET_TP_SRC:
275     case OFPUTIL_OFPAT_SET_TP_DST:
276         oata = ofputil_put_action(code, b);
277         oata->tp_port = htons(str_to_u32(arg));
278         break;
279
280     case OFPUTIL_OFPAT_ENQUEUE:
281         parse_enqueue(b, arg);
282         break;
283
284     case OFPUTIL_NXAST_RESUBMIT:
285         parse_resubmit(b, arg);
286         break;
287
288     case OFPUTIL_NXAST_SET_TUNNEL:
289         parse_set_tunnel(b, arg);
290         break;
291
292     case OFPUTIL_NXAST_SET_QUEUE:
293         ofputil_put_NXAST_SET_QUEUE(b)->queue_id = htonl(str_to_u32(arg));
294         break;
295
296     case OFPUTIL_NXAST_POP_QUEUE:
297         ofputil_put_NXAST_POP_QUEUE(b);
298         break;
299
300     case OFPUTIL_NXAST_REG_MOVE:
301         nxm_parse_reg_move(ofputil_put_NXAST_REG_MOVE(b), arg);
302         break;
303
304     case OFPUTIL_NXAST_REG_LOAD:
305         nxm_parse_reg_load(ofputil_put_NXAST_REG_LOAD(b), arg);
306         break;
307
308     case OFPUTIL_NXAST_NOTE:
309         parse_note(b, arg);
310         break;
311
312     case OFPUTIL_NXAST_SET_TUNNEL64:
313         ofputil_put_NXAST_SET_TUNNEL64(b)->tun_id = htonll(str_to_u64(arg));
314         break;
315
316     case OFPUTIL_NXAST_MULTIPATH:
317         multipath_parse(ofputil_put_NXAST_MULTIPATH(b), arg);
318         break;
319
320     case OFPUTIL_NXAST_AUTOPATH:
321         autopath_parse(ofputil_put_NXAST_AUTOPATH(b), arg);
322         break;
323
324     case OFPUTIL_NXAST_BUNDLE:
325         bundle_parse(b, arg);
326         break;
327
328     case OFPUTIL_NXAST_BUNDLE_LOAD:
329         bundle_parse_load(b, arg);
330         break;
331
332     case OFPUTIL_NXAST_RESUBMIT_TABLE:
333     case OFPUTIL_NXAST_OUTPUT_REG:
334         NOT_REACHED();
335     }
336 }
337
338 static void
339 str_to_action(char *str, struct ofpbuf *b)
340 {
341     char *pos, *act, *arg;
342     int n_actions;
343
344     pos = str;
345     n_actions = 0;
346     while (ofputil_parse_key_value(&pos, &act, &arg)) {
347         uint16_t port;
348         int code;
349
350         code = ofputil_action_code_from_name(act);
351         if (code >= 0) {
352             parse_named_action(code, b, arg);
353         } else if (!strcasecmp(act, "drop")) {
354             /* A drop action in OpenFlow occurs by just not setting
355              * an action. */
356             if (n_actions) {
357                 ovs_fatal(0, "Drop actions must not be preceded by other "
358                           "actions");
359             } else if (ofputil_parse_key_value(&pos, &act, &arg)) {
360                 ovs_fatal(0, "Drop actions must not be followed by other "
361                           "actions");
362             }
363             break;
364         } else if (!strcasecmp(act, "CONTROLLER")) {
365             struct ofp_action_output *oao;
366             oao = put_output_action(b, OFPP_CONTROLLER);
367
368             /* Unless a numeric argument is specified, we send the whole
369              * packet to the controller. */
370             if (arg[0] && (strspn(arg, "0123456789") == strlen(arg))) {
371                oao->max_len = htons(str_to_u32(arg));
372             } else {
373                 oao->max_len = htons(UINT16_MAX);
374             }
375         } else if (ofputil_port_from_string(act, &port)) {
376             put_output_action(b, port);
377         } else {
378             ovs_fatal(0, "Unknown action: %s", act);
379         }
380         n_actions++;
381     }
382 }
383
384 struct protocol {
385     const char *name;
386     uint16_t dl_type;
387     uint8_t nw_proto;
388 };
389
390 static bool
391 parse_protocol(const char *name, const struct protocol **p_out)
392 {
393     static const struct protocol protocols[] = {
394         { "ip", ETH_TYPE_IP, 0 },
395         { "arp", ETH_TYPE_ARP, 0 },
396         { "icmp", ETH_TYPE_IP, IPPROTO_ICMP },
397         { "tcp", ETH_TYPE_IP, IPPROTO_TCP },
398         { "udp", ETH_TYPE_IP, IPPROTO_UDP },
399         { "ipv6", ETH_TYPE_IPV6, 0 },
400         { "ip6", ETH_TYPE_IPV6, 0 },
401         { "icmp6", ETH_TYPE_IPV6, IPPROTO_ICMPV6 },
402         { "tcp6", ETH_TYPE_IPV6, IPPROTO_TCP },
403         { "udp6", ETH_TYPE_IPV6, IPPROTO_UDP },
404     };
405     const struct protocol *p;
406
407     for (p = protocols; p < &protocols[ARRAY_SIZE(protocols)]; p++) {
408         if (!strcmp(p->name, name)) {
409             *p_out = p;
410             return true;
411         }
412     }
413     *p_out = NULL;
414     return false;
415 }
416
417 static void
418 ofp_fatal(const char *flow, bool verbose, const char *format, ...)
419 {
420     va_list args;
421
422     if (verbose) {
423         fprintf(stderr, "%s:\n", flow);
424     }
425
426     va_start(args, format);
427     ovs_fatal_valist(0, format, args);
428 }
429
430 static void
431 parse_field(const struct mf_field *mf, const char *s, struct cls_rule *rule)
432 {
433     union mf_value value, mask;
434     char *error;
435
436     error = mf_parse(mf, s, &value, &mask);
437     if (error) {
438         ovs_fatal(0, "%s", error);
439     }
440
441     mf_set(mf, &value, &mask, rule);
442 }
443
444 /* Convert 'str_' (as described in the Flow Syntax section of the ovs-ofctl man
445  * page) into 'fm' for sending the specified flow_mod 'command' to a switch.
446  * If 'actions' is specified, an action must be in 'string' and may be expanded
447  * or reallocated.
448  *
449  * To parse syntax for an OFPT_FLOW_MOD (or NXT_FLOW_MOD), use an OFPFC_*
450  * constant for 'command'.  To parse syntax for an OFPST_FLOW or
451  * OFPST_AGGREGATE (or NXST_FLOW or NXST_AGGREGATE), use -1 for 'command'. */
452 void
453 parse_ofp_str(struct ofputil_flow_mod *fm, int command, const char *str_,
454               bool verbose)
455 {
456     enum {
457         F_OUT_PORT = 1 << 0,
458         F_ACTIONS = 1 << 1,
459         F_COOKIE = 1 << 2,
460         F_TIMEOUT = 1 << 3,
461         F_PRIORITY = 1 << 4
462     } fields;
463     char *string = xstrdup(str_);
464     char *save_ptr = NULL;
465     char *name;
466
467     switch (command) {
468     case -1:
469         fields = F_OUT_PORT;
470         break;
471
472     case OFPFC_ADD:
473         fields = F_ACTIONS | F_COOKIE | F_TIMEOUT | F_PRIORITY;
474         break;
475
476     case OFPFC_DELETE:
477         fields = F_OUT_PORT;
478         break;
479
480     case OFPFC_DELETE_STRICT:
481         fields = F_OUT_PORT | F_PRIORITY;
482         break;
483
484     case OFPFC_MODIFY:
485         fields = F_ACTIONS | F_COOKIE;
486         break;
487
488     case OFPFC_MODIFY_STRICT:
489         fields = F_ACTIONS | F_COOKIE | F_PRIORITY;
490         break;
491
492     default:
493         NOT_REACHED();
494     }
495
496     cls_rule_init_catchall(&fm->cr, OFP_DEFAULT_PRIORITY);
497     fm->cookie = htonll(0);
498     fm->table_id = 0xff;
499     fm->command = command;
500     fm->idle_timeout = OFP_FLOW_PERMANENT;
501     fm->hard_timeout = OFP_FLOW_PERMANENT;
502     fm->buffer_id = UINT32_MAX;
503     fm->out_port = OFPP_NONE;
504     fm->flags = 0;
505     if (fields & F_ACTIONS) {
506         struct ofpbuf actions;
507         char *act_str;
508
509         act_str = strstr(string, "action");
510         if (!act_str) {
511             ofp_fatal(str_, verbose, "must specify an action");
512         }
513         *act_str = '\0';
514
515         act_str = strchr(act_str + 1, '=');
516         if (!act_str) {
517             ofp_fatal(str_, verbose, "must specify an action");
518         }
519
520         act_str++;
521
522         ofpbuf_init(&actions, sizeof(union ofp_action));
523         str_to_action(act_str, &actions);
524         fm->actions = ofpbuf_steal_data(&actions);
525         fm->n_actions = actions.size / sizeof(union ofp_action);
526     } else {
527         fm->actions = NULL;
528         fm->n_actions = 0;
529     }
530     for (name = strtok_r(string, "=, \t\r\n", &save_ptr); name;
531          name = strtok_r(NULL, "=, \t\r\n", &save_ptr)) {
532         const struct protocol *p;
533
534         if (parse_protocol(name, &p)) {
535             cls_rule_set_dl_type(&fm->cr, htons(p->dl_type));
536             if (p->nw_proto) {
537                 cls_rule_set_nw_proto(&fm->cr, p->nw_proto);
538             }
539         } else {
540             char *value;
541
542             value = strtok_r(NULL, ", \t\r\n", &save_ptr);
543             if (!value) {
544                 ofp_fatal(str_, verbose, "field %s missing value", name);
545             }
546
547             if (!strcmp(name, "table")) {
548                 fm->table_id = atoi(value);
549             } else if (!strcmp(name, "out_port")) {
550                 fm->out_port = atoi(value);
551             } else if (fields & F_PRIORITY && !strcmp(name, "priority")) {
552                 fm->cr.priority = atoi(value);
553             } else if (fields & F_TIMEOUT && !strcmp(name, "idle_timeout")) {
554                 fm->idle_timeout = atoi(value);
555             } else if (fields & F_TIMEOUT && !strcmp(name, "hard_timeout")) {
556                 fm->hard_timeout = atoi(value);
557             } else if (fields & F_COOKIE && !strcmp(name, "cookie")) {
558                 fm->cookie = htonll(str_to_u64(value));
559             } else if (mf_from_name(name)) {
560                 parse_field(mf_from_name(name), value, &fm->cr);
561             } else if (!strcmp(name, "duration")
562                        || !strcmp(name, "n_packets")
563                        || !strcmp(name, "n_bytes")) {
564                 /* Ignore these, so that users can feed the output of
565                  * "ovs-ofctl dump-flows" back into commands that parse
566                  * flows. */
567             } else {
568                 ofp_fatal(str_, verbose, "unknown keyword %s", name);
569             }
570         }
571     }
572
573     free(string);
574 }
575
576 /* Parses 'string' as an OFPT_FLOW_MOD or NXT_FLOW_MOD with command 'command'
577  * (one of OFPFC_*) and appends the parsed OpenFlow message to 'packets'.
578  * '*cur_format' should initially contain the flow format currently configured
579  * on the connection; this function will add a message to change the flow
580  * format and update '*cur_format', if this is necessary to add the parsed
581  * flow. */
582 void
583 parse_ofp_flow_mod_str(struct list *packets, enum nx_flow_format *cur_format,
584                        bool *flow_mod_table_id, char *string, uint16_t command,
585                        bool verbose)
586 {
587     enum nx_flow_format min_format, next_format;
588     struct cls_rule rule_copy;
589     struct ofpbuf actions;
590     struct ofpbuf *ofm;
591     struct ofputil_flow_mod fm;
592
593     ofpbuf_init(&actions, 64);
594     parse_ofp_str(&fm, command, string, verbose);
595
596     min_format = ofputil_min_flow_format(&fm.cr);
597     next_format = MAX(*cur_format, min_format);
598     if (next_format != *cur_format) {
599         struct ofpbuf *sff = ofputil_make_set_flow_format(next_format);
600         list_push_back(packets, &sff->list_node);
601         *cur_format = next_format;
602     }
603
604     /* Normalize a copy of the rule.  This ensures that non-normalized flows
605      * get logged but doesn't affect what gets sent to the switch, so that the
606      * switch can do whatever it likes with the flow. */
607     rule_copy = fm.cr;
608     ofputil_normalize_rule(&rule_copy, next_format);
609
610     if (fm.table_id != 0xff && !*flow_mod_table_id) {
611         struct ofpbuf *sff = ofputil_make_flow_mod_table_id(true);
612         list_push_back(packets, &sff->list_node);
613         *flow_mod_table_id = true;
614     }
615
616     ofm = ofputil_encode_flow_mod(&fm, *cur_format, *flow_mod_table_id);
617     list_push_back(packets, &ofm->list_node);
618
619     ofpbuf_uninit(&actions);
620 }
621
622 /* Similar to parse_ofp_flow_mod_str(), except that the string is read from
623  * 'stream' and the command is always OFPFC_ADD.  Returns false if end-of-file
624  * is reached before reading a flow, otherwise true. */
625 bool
626 parse_ofp_flow_mod_file(struct list *packets,
627                         enum nx_flow_format *cur, bool *flow_mod_table_id,
628                         FILE *stream, uint16_t command)
629 {
630     struct ds s;
631     bool ok;
632
633     ds_init(&s);
634     ok = ds_get_preprocessed_line(&s, stream) == 0;
635     if (ok) {
636         parse_ofp_flow_mod_str(packets, cur, flow_mod_table_id,
637                                ds_cstr(&s), command, true);
638     }
639     ds_destroy(&s);
640
641     return ok;
642 }
643
644 void
645 parse_ofp_flow_stats_request_str(struct ofputil_flow_stats_request *fsr,
646                                  bool aggregate, char *string)
647 {
648     struct ofputil_flow_mod fm;
649
650     parse_ofp_str(&fm, -1, string, false);
651     fsr->aggregate = aggregate;
652     fsr->match = fm.cr;
653     fsr->out_port = fm.out_port;
654     fsr->table_id = fm.table_id;
655 }