ovn-controller: Add 'put_dhcp_opts' action in ovn-controller
[cascardo/ovs.git] / ovn / controller / lflow.c
1 /* Copyright (c) 2015, 2016 Nicira, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <config.h>
17 #include "lflow.h"
18 #include "lport.h"
19 #include "ofctrl.h"
20 #include "openvswitch/dynamic-string.h"
21 #include "openvswitch/ofp-actions.h"
22 #include "openvswitch/ofpbuf.h"
23 #include "openvswitch/vlog.h"
24 #include "ovn-controller.h"
25 #include "ovn/lib/actions.h"
26 #include "ovn/lib/expr.h"
27 #include "ovn/lib/ovn-dhcp.h"
28 #include "ovn/lib/ovn-sb-idl.h"
29 #include "packets.h"
30 #include "simap.h"
31
32 VLOG_DEFINE_THIS_MODULE(lflow);
33 \f
34 /* Symbol table. */
35
36 /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */
37 static struct shash symtab;
38
39 static void
40 add_logical_register(struct shash *symtab, enum mf_field_id id)
41 {
42     char name[8];
43
44     snprintf(name, sizeof name, "reg%d", id - MFF_REG0);
45     expr_symtab_add_field(symtab, name, id, NULL, false);
46 }
47
48 void
49 lflow_init(void)
50 {
51     shash_init(&symtab);
52
53     /* Reserve a pair of registers for the logical inport and outport.  A full
54      * 32-bit register each is bigger than we need, but the expression code
55      * doesn't yet support string fields that occupy less than a full OXM. */
56     expr_symtab_add_string(&symtab, "inport", MFF_LOG_INPORT, NULL);
57     expr_symtab_add_string(&symtab, "outport", MFF_LOG_OUTPORT, NULL);
58
59     /* Logical registers. */
60 #define MFF_LOG_REG(ID) add_logical_register(&symtab, ID);
61     MFF_LOG_REGS;
62 #undef MFF_LOG_REG
63
64     /* Connection tracking state. */
65     expr_symtab_add_field(&symtab, "ct_mark", MFF_CT_MARK, NULL, false);
66     expr_symtab_add_field(&symtab, "ct_label", MFF_CT_LABEL, NULL, false);
67     expr_symtab_add_field(&symtab, "ct_state", MFF_CT_STATE, NULL, false);
68     char ct_state_str[16];
69     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_TRACKED_BIT);
70     expr_symtab_add_predicate(&symtab, "ct.trk", ct_state_str);
71     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_NEW_BIT);
72     expr_symtab_add_subfield(&symtab, "ct.new", "ct.trk", ct_state_str);
73     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_ESTABLISHED_BIT);
74     expr_symtab_add_subfield(&symtab, "ct.est", "ct.trk", ct_state_str);
75     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_RELATED_BIT);
76     expr_symtab_add_subfield(&symtab, "ct.rel", "ct.trk", ct_state_str);
77     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_REPLY_DIR_BIT);
78     expr_symtab_add_subfield(&symtab, "ct.rpl", "ct.trk", ct_state_str);
79     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_INVALID_BIT);
80     expr_symtab_add_subfield(&symtab, "ct.inv", "ct.trk", ct_state_str);
81
82     /* Data fields. */
83     expr_symtab_add_field(&symtab, "eth.src", MFF_ETH_SRC, NULL, false);
84     expr_symtab_add_field(&symtab, "eth.dst", MFF_ETH_DST, NULL, false);
85     expr_symtab_add_field(&symtab, "eth.type", MFF_ETH_TYPE, NULL, true);
86     expr_symtab_add_predicate(&symtab, "eth.bcast",
87                               "eth.dst == ff:ff:ff:ff:ff:ff");
88     expr_symtab_add_subfield(&symtab, "eth.mcast", NULL, "eth.dst[40]");
89
90     expr_symtab_add_field(&symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false);
91     expr_symtab_add_predicate(&symtab, "vlan.present", "vlan.tci[12]");
92     expr_symtab_add_subfield(&symtab, "vlan.pcp", "vlan.present",
93                              "vlan.tci[13..15]");
94     expr_symtab_add_subfield(&symtab, "vlan.vid", "vlan.present",
95                              "vlan.tci[0..11]");
96
97     expr_symtab_add_predicate(&symtab, "ip4", "eth.type == 0x800");
98     expr_symtab_add_predicate(&symtab, "ip6", "eth.type == 0x86dd");
99     expr_symtab_add_predicate(&symtab, "ip", "ip4 || ip6");
100     expr_symtab_add_field(&symtab, "ip.proto", MFF_IP_PROTO, "ip", true);
101     expr_symtab_add_field(&symtab, "ip.dscp", MFF_IP_DSCP, "ip", false);
102     expr_symtab_add_field(&symtab, "ip.ecn", MFF_IP_ECN, "ip", false);
103     expr_symtab_add_field(&symtab, "ip.ttl", MFF_IP_TTL, "ip", false);
104
105     expr_symtab_add_field(&symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false);
106     expr_symtab_add_field(&symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false);
107     expr_symtab_add_predicate(&symtab, "ip4.mcast", "ip4.dst[28..31] == 0xe");
108
109     expr_symtab_add_predicate(&symtab, "icmp4", "ip4 && ip.proto == 1");
110     expr_symtab_add_field(&symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4",
111               false);
112     expr_symtab_add_field(&symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4",
113               false);
114
115     expr_symtab_add_field(&symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false);
116     expr_symtab_add_field(&symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false);
117     expr_symtab_add_field(&symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", false);
118
119     expr_symtab_add_predicate(&symtab, "icmp6", "ip6 && ip.proto == 58");
120     expr_symtab_add_field(&symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6",
121                           true);
122     expr_symtab_add_field(&symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6",
123                           true);
124
125     expr_symtab_add_predicate(&symtab, "icmp", "icmp4 || icmp6");
126
127     expr_symtab_add_field(&symtab, "ip.frag", MFF_IP_FRAG, "ip", false);
128     expr_symtab_add_predicate(&symtab, "ip.is_frag", "ip.frag[0]");
129     expr_symtab_add_predicate(&symtab, "ip.later_frag", "ip.frag[1]");
130     expr_symtab_add_predicate(&symtab, "ip.first_frag",
131                               "ip.is_frag && !ip.later_frag");
132
133     expr_symtab_add_predicate(&symtab, "arp", "eth.type == 0x806");
134     expr_symtab_add_field(&symtab, "arp.op", MFF_ARP_OP, "arp", false);
135     expr_symtab_add_field(&symtab, "arp.spa", MFF_ARP_SPA, "arp", false);
136     expr_symtab_add_field(&symtab, "arp.sha", MFF_ARP_SHA, "arp", false);
137     expr_symtab_add_field(&symtab, "arp.tpa", MFF_ARP_TPA, "arp", false);
138     expr_symtab_add_field(&symtab, "arp.tha", MFF_ARP_THA, "arp", false);
139
140     expr_symtab_add_predicate(&symtab, "nd",
141                               "icmp6.type == {135, 136} && icmp6.code == 0");
142     expr_symtab_add_field(&symtab, "nd.target", MFF_ND_TARGET, "nd", false);
143     expr_symtab_add_field(&symtab, "nd.sll", MFF_ND_SLL,
144               "nd && icmp6.type == 135", false);
145     expr_symtab_add_field(&symtab, "nd.tll", MFF_ND_TLL,
146               "nd && icmp6.type == 136", false);
147
148     expr_symtab_add_predicate(&symtab, "tcp", "ip.proto == 6");
149     expr_symtab_add_field(&symtab, "tcp.src", MFF_TCP_SRC, "tcp", false);
150     expr_symtab_add_field(&symtab, "tcp.dst", MFF_TCP_DST, "tcp", false);
151     expr_symtab_add_field(&symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", false);
152
153     expr_symtab_add_predicate(&symtab, "udp", "ip.proto == 17");
154     expr_symtab_add_field(&symtab, "udp.src", MFF_UDP_SRC, "udp", false);
155     expr_symtab_add_field(&symtab, "udp.dst", MFF_UDP_DST, "udp", false);
156
157     expr_symtab_add_predicate(&symtab, "sctp", "ip.proto == 132");
158     expr_symtab_add_field(&symtab, "sctp.src", MFF_SCTP_SRC, "sctp", false);
159     expr_symtab_add_field(&symtab, "sctp.dst", MFF_SCTP_DST, "sctp", false);
160 }
161 \f
162 struct lookup_port_aux {
163     const struct lport_index *lports;
164     const struct mcgroup_index *mcgroups;
165     const struct sbrec_datapath_binding *dp;
166 };
167
168 static bool
169 lookup_port_cb(const void *aux_, const char *port_name, unsigned int *portp)
170 {
171     const struct lookup_port_aux *aux = aux_;
172
173     const struct sbrec_port_binding *pb
174         = lport_lookup_by_name(aux->lports, port_name);
175     if (pb && pb->datapath == aux->dp) {
176         *portp = pb->tunnel_key;
177         return true;
178     }
179
180     const struct sbrec_multicast_group *mg
181         = mcgroup_lookup_by_dp_name(aux->mcgroups, aux->dp, port_name);
182     if (mg) {
183         *portp = mg->tunnel_key;
184         return true;
185     }
186
187     return false;
188 }
189
190 static bool
191 is_switch(const struct sbrec_datapath_binding *ldp)
192 {
193     return smap_get(&ldp->external_ids, "logical-switch") != NULL;
194
195 }
196
197 /* Adds the logical flows from the Logical_Flow table to 'flow_table'. */
198 static void
199 add_logical_flows(struct controller_ctx *ctx, const struct lport_index *lports,
200                   const struct mcgroup_index *mcgroups,
201                   const struct hmap *local_datapaths,
202                   const struct hmap *patched_datapaths,
203                   const struct simap *ct_zones, struct hmap *flow_table)
204 {
205     uint32_t conj_id_ofs = 1;
206
207     struct hmap dhcp_opts = HMAP_INITIALIZER(&dhcp_opts);
208     const struct sbrec_dhcp_options *dhcp_opt_row;
209     SBREC_DHCP_OPTIONS_FOR_EACH(dhcp_opt_row, ctx->ovnsb_idl) {
210         dhcp_opt_add(&dhcp_opts, dhcp_opt_row->name, dhcp_opt_row->code,
211                      dhcp_opt_row->type);
212     }
213
214     const struct sbrec_logical_flow *lflow;
215     SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
216         /* Determine translation of logical table IDs to physical table IDs. */
217         bool ingress = !strcmp(lflow->pipeline, "ingress");
218
219         const struct sbrec_datapath_binding *ldp = lflow->logical_datapath;
220         if (!ldp) {
221             continue;
222         }
223         if (is_switch(ldp)) {
224             /* For a logical switch datapath, local_datapaths tells us if there
225              * are any local ports for this datapath.  If not, we can skip
226              * processing logical flows if that logical switch datapath is not
227              * patched to any logical router.
228              *
229              * Otherwise, we still need both ingress and egress pipeline
230              * because even if there are no local ports, we still may need to
231              * execute the ingress pipeline after a packet leaves a logical
232              * router and we need to do egress pipeline for a switch that
233              * is connected to only routers.  Further optimization is possible,
234              * but not based on what we know with local_datapaths right now.
235              *
236              * A better approach would be a kind of "flood fill" algorithm:
237              *
238              *   1. Initialize set S to the logical datapaths that have a port
239              *      located on the hypervisor.
240              *
241              *   2. For each patch port P in a logical datapath in S, add the
242              *      logical datapath of the remote end of P to S.  Iterate
243              *      until S reaches a fixed point.
244              *
245              * This can be implemented in northd, which can generate the sets and
246              * save it on each port-binding record in SB, and ovn-controller can
247              * use the information directly. However, there can be update storms
248              * when a pair of patch ports are added/removed to connect/disconnect
249              * large lrouters and lswitches. This need to be studied further.
250              */
251
252             if (!get_local_datapath(local_datapaths, ldp->tunnel_key)) {
253                 if (!get_patched_datapath(patched_datapaths,
254                                           ldp->tunnel_key)) {
255                     continue;
256                 }
257             }
258         }
259
260         /* Determine translation of logical table IDs to physical table IDs. */
261         uint8_t first_ptable = (ingress
262                                 ? OFTABLE_LOG_INGRESS_PIPELINE
263                                 : OFTABLE_LOG_EGRESS_PIPELINE);
264         uint8_t ptable = first_ptable + lflow->table_id;
265         uint8_t output_ptable = (ingress
266                                  ? OFTABLE_REMOTE_OUTPUT
267                                  : OFTABLE_LOG_TO_PHY);
268
269         /* Translate OVN actions into OpenFlow actions.
270          *
271          * XXX Deny changes to 'outport' in egress pipeline. */
272         uint64_t ofpacts_stub[64 / 8];
273         struct ofpbuf ofpacts;
274         struct expr *prereqs;
275         char *error;
276
277         ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
278         struct lookup_port_aux aux = {
279             .lports = lports,
280             .mcgroups = mcgroups,
281             .dp = lflow->logical_datapath
282         };
283         struct action_params ap = {
284             .symtab = &symtab,
285             .dhcp_opts = &dhcp_opts,
286             .lookup_port = lookup_port_cb,
287             .aux = &aux,
288             .ct_zones = ct_zones,
289
290             .n_tables = LOG_PIPELINE_LEN,
291             .first_ptable = first_ptable,
292             .cur_ltable = lflow->table_id,
293             .output_ptable = output_ptable,
294             .arp_ptable = OFTABLE_MAC_BINDING,
295         };
296         error = actions_parse_string(lflow->actions, &ap, &ofpacts, &prereqs);
297         if (error) {
298             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
299             VLOG_WARN_RL(&rl, "error parsing actions \"%s\": %s",
300                          lflow->actions, error);
301             free(error);
302             continue;
303         }
304
305         /* Translate OVN match into table of OpenFlow matches. */
306         struct hmap matches;
307         struct expr *expr;
308
309         expr = expr_parse_string(lflow->match, &symtab, &error);
310         if (!error) {
311             if (prereqs) {
312                 expr = expr_combine(EXPR_T_AND, expr, prereqs);
313                 prereqs = NULL;
314             }
315             expr = expr_annotate(expr, &symtab, &error);
316         }
317         if (error) {
318             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
319             VLOG_WARN_RL(&rl, "error parsing match \"%s\": %s",
320                          lflow->match, error);
321             expr_destroy(prereqs);
322             ofpbuf_uninit(&ofpacts);
323             free(error);
324             continue;
325         }
326
327         expr = expr_simplify(expr);
328         expr = expr_normalize(expr);
329         uint32_t n_conjs = expr_to_matches(expr, lookup_port_cb, &aux,
330                                            &matches);
331         expr_destroy(expr);
332
333         /* Prepare the OpenFlow matches for adding to the flow table. */
334         struct expr_match *m;
335         HMAP_FOR_EACH (m, hmap_node, &matches) {
336             match_set_metadata(&m->match,
337                                htonll(lflow->logical_datapath->tunnel_key));
338             if (m->match.wc.masks.conj_id) {
339                 m->match.flow.conj_id += conj_id_ofs;
340             }
341             if (!m->n) {
342                 ofctrl_add_flow(flow_table, ptable, lflow->priority,
343                                 &m->match, &ofpacts);
344             } else {
345                 uint64_t conj_stubs[64 / 8];
346                 struct ofpbuf conj;
347
348                 ofpbuf_use_stub(&conj, conj_stubs, sizeof conj_stubs);
349                 for (int i = 0; i < m->n; i++) {
350                     const struct cls_conjunction *src = &m->conjunctions[i];
351                     struct ofpact_conjunction *dst;
352
353                     dst = ofpact_put_CONJUNCTION(&conj);
354                     dst->id = src->id + conj_id_ofs;
355                     dst->clause = src->clause;
356                     dst->n_clauses = src->n_clauses;
357                 }
358                 ofctrl_add_flow(flow_table, ptable, lflow->priority,
359                                 &m->match, &conj);
360                 ofpbuf_uninit(&conj);
361             }
362         }
363
364         /* Clean up. */
365         expr_matches_destroy(&matches);
366         ofpbuf_uninit(&ofpacts);
367         conj_id_ofs += n_conjs;
368     }
369
370     dhcp_opts_destroy(&dhcp_opts);
371 }
372
373 static void
374 put_load(const uint8_t *data, size_t len,
375          enum mf_field_id dst, int ofs, int n_bits,
376          struct ofpbuf *ofpacts)
377 {
378     struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
379     sf->field = mf_from_id(dst);
380     sf->flow_has_vlan = false;
381
382     bitwise_copy(data, len, 0, &sf->value, sf->field->n_bytes, ofs, n_bits);
383     bitwise_one(&sf->mask, sf->field->n_bytes, ofs, n_bits);
384 }
385
386 /* Adds an OpenFlow flow to 'flow_table' for each MAC binding in the OVN
387  * southbound database, using 'lports' to resolve logical port names to
388  * numbers. */
389 static void
390 add_neighbor_flows(struct controller_ctx *ctx,
391                    const struct lport_index *lports, struct hmap *flow_table)
392 {
393     struct ofpbuf ofpacts;
394     struct match match;
395     match_init_catchall(&match);
396     ofpbuf_init(&ofpacts, 0);
397
398     const struct sbrec_mac_binding *b;
399     SBREC_MAC_BINDING_FOR_EACH (b, ctx->ovnsb_idl) {
400         const struct sbrec_port_binding *pb
401             = lport_lookup_by_name(lports, b->logical_port);
402         if (!pb) {
403             continue;
404         }
405
406         struct eth_addr mac;
407         if (!eth_addr_from_string(b->mac, &mac)) {
408             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
409             VLOG_WARN_RL(&rl, "bad 'mac' %s", b->mac);
410             continue;
411         }
412
413         ovs_be32 ip;
414         if (!ip_parse(b->ip, &ip)) {
415             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
416             VLOG_WARN_RL(&rl, "bad 'ip' %s", b->ip);
417             continue;
418         }
419
420         match_set_metadata(&match, htonll(pb->datapath->tunnel_key));
421         match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, pb->tunnel_key);
422         match_set_reg(&match, 0, ntohl(ip));
423
424         ofpbuf_clear(&ofpacts);
425         put_load(mac.ea, sizeof mac.ea, MFF_ETH_DST, 0, 48, &ofpacts);
426
427         ofctrl_add_flow(flow_table, OFTABLE_MAC_BINDING, 100,
428                         &match, &ofpacts);
429     }
430     ofpbuf_uninit(&ofpacts);
431 }
432 \f
433 /* Translates logical flows in the Logical_Flow table in the OVN_SB database
434  * into OpenFlow flows.  See ovn-architecture(7) for more information. */
435 void
436 lflow_run(struct controller_ctx *ctx, const struct lport_index *lports,
437           const struct mcgroup_index *mcgroups,
438           const struct hmap *local_datapaths,
439           const struct hmap *patched_datapaths,
440           const struct simap *ct_zones, struct hmap *flow_table)
441 {
442     add_logical_flows(ctx, lports, mcgroups, local_datapaths,
443                       patched_datapaths, ct_zones, flow_table);
444     add_neighbor_flows(ctx, lports, flow_table);
445 }
446
447 void
448 lflow_destroy(void)
449 {
450     expr_symtab_destroy(&symtab);
451     shash_destroy(&symtab);
452 }