ovn: Rename Pipeline table to Logical_Flow table.
[cascardo/ovs.git] / ovn / controller / lflow.c
1 /* Copyright (c) 2015 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 "dynamic-string.h"
19 #include "ofctrl.h"
20 #include "ofp-actions.h"
21 #include "ofpbuf.h"
22 #include "openvswitch/vlog.h"
23 #include "ovn/controller/ovn-controller.h"
24 #include "ovn/lib/actions.h"
25 #include "ovn/lib/expr.h"
26 #include "ovn/lib/ovn-sb-idl.h"
27 #include "simap.h"
28
29 VLOG_DEFINE_THIS_MODULE(lflow);
30 \f
31 /* Symbol table. */
32
33 /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */
34 static struct shash symtab;
35
36 static void
37 symtab_init(void)
38 {
39     shash_init(&symtab);
40
41     /* Reserve a pair of registers for the logical inport and outport.  A full
42      * 32-bit register each is bigger than we need, but the expression code
43      * doesn't yet support string fields that occupy less than a full OXM. */
44     expr_symtab_add_string(&symtab, "inport", MFF_LOG_INPORT, NULL);
45     expr_symtab_add_string(&symtab, "outport", MFF_LOG_OUTPORT, NULL);
46
47     /* Registers.  We omit the registers that would otherwise overlap the
48      * reserved fields. */
49     for (enum mf_field_id id = MFF_REG0; id < MFF_REG0 + FLOW_N_REGS; id++) {
50         if (id != MFF_LOG_INPORT && id != MFF_LOG_OUTPORT) {
51             char name[8];
52
53             snprintf(name, sizeof name, "reg%d", id - MFF_REG0);
54             expr_symtab_add_field(&symtab, name, id, NULL, false);
55         }
56     }
57
58     /* Data fields. */
59     expr_symtab_add_field(&symtab, "eth.src", MFF_ETH_SRC, NULL, false);
60     expr_symtab_add_field(&symtab, "eth.dst", MFF_ETH_DST, NULL, false);
61     expr_symtab_add_field(&symtab, "eth.type", MFF_ETH_TYPE, NULL, true);
62
63     expr_symtab_add_field(&symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false);
64     expr_symtab_add_predicate(&symtab, "vlan.present", "vlan.tci[12]");
65     expr_symtab_add_subfield(&symtab, "vlan.pcp", "vlan.present",
66                              "vlan.tci[13..15]");
67     expr_symtab_add_subfield(&symtab, "vlan.vid", "vlan.present",
68                              "vlan.tci[0..11]");
69
70     expr_symtab_add_predicate(&symtab, "ip4", "eth.type == 0x800");
71     expr_symtab_add_predicate(&symtab, "ip6", "eth.type == 0x86dd");
72     expr_symtab_add_predicate(&symtab, "ip", "ip4 || ip6");
73     expr_symtab_add_field(&symtab, "ip.proto", MFF_IP_PROTO, "ip", true);
74     expr_symtab_add_field(&symtab, "ip.dscp", MFF_IP_DSCP, "ip", false);
75     expr_symtab_add_field(&symtab, "ip.ecn", MFF_IP_ECN, "ip", false);
76     expr_symtab_add_field(&symtab, "ip.ttl", MFF_IP_TTL, "ip", false);
77
78     expr_symtab_add_field(&symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false);
79     expr_symtab_add_field(&symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false);
80
81     expr_symtab_add_predicate(&symtab, "icmp4", "ip4 && ip.proto == 1");
82     expr_symtab_add_field(&symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4",
83               false);
84     expr_symtab_add_field(&symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4",
85               false);
86
87     expr_symtab_add_field(&symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false);
88     expr_symtab_add_field(&symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false);
89     expr_symtab_add_field(&symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", false);
90
91     expr_symtab_add_predicate(&symtab, "icmp6", "ip6 && ip.proto == 58");
92     expr_symtab_add_field(&symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6",
93                           true);
94     expr_symtab_add_field(&symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6",
95                           true);
96
97     expr_symtab_add_predicate(&symtab, "icmp", "icmp4 || icmp6");
98
99     expr_symtab_add_field(&symtab, "ip.frag", MFF_IP_FRAG, "ip", false);
100     expr_symtab_add_predicate(&symtab, "ip.is_frag", "ip.frag[0]");
101     expr_symtab_add_predicate(&symtab, "ip.later_frag", "ip.frag[1]");
102     expr_symtab_add_predicate(&symtab, "ip.first_frag",
103                               "ip.is_frag && !ip.later_frag");
104
105     expr_symtab_add_predicate(&symtab, "arp", "eth.type == 0x806");
106     expr_symtab_add_field(&symtab, "arp.op", MFF_ARP_OP, "arp", false);
107     expr_symtab_add_field(&symtab, "arp.spa", MFF_ARP_SPA, "arp", false);
108     expr_symtab_add_field(&symtab, "arp.sha", MFF_ARP_SHA, "arp", false);
109     expr_symtab_add_field(&symtab, "arp.tpa", MFF_ARP_TPA, "arp", false);
110     expr_symtab_add_field(&symtab, "arp.tha", MFF_ARP_THA, "arp", false);
111
112     expr_symtab_add_predicate(&symtab, "nd",
113                               "icmp6.type == {135, 136} && icmp6.code == 0");
114     expr_symtab_add_field(&symtab, "nd.target", MFF_ND_TARGET, "nd", false);
115     expr_symtab_add_field(&symtab, "nd.sll", MFF_ND_SLL,
116               "nd && icmp6.type == 135", false);
117     expr_symtab_add_field(&symtab, "nd.tll", MFF_ND_TLL,
118               "nd && icmp6.type == 136", false);
119
120     expr_symtab_add_predicate(&symtab, "tcp", "ip.proto == 6");
121     expr_symtab_add_field(&symtab, "tcp.src", MFF_TCP_SRC, "tcp", false);
122     expr_symtab_add_field(&symtab, "tcp.dst", MFF_TCP_DST, "tcp", false);
123     expr_symtab_add_field(&symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", false);
124
125     expr_symtab_add_predicate(&symtab, "udp", "ip.proto == 17");
126     expr_symtab_add_field(&symtab, "udp.src", MFF_UDP_SRC, "udp", false);
127     expr_symtab_add_field(&symtab, "udp.dst", MFF_UDP_DST, "udp", false);
128
129     expr_symtab_add_predicate(&symtab, "sctp", "ip.proto == 132");
130     expr_symtab_add_field(&symtab, "sctp.src", MFF_SCTP_SRC, "sctp", false);
131     expr_symtab_add_field(&symtab, "sctp.dst", MFF_SCTP_DST, "sctp", false);
132 }
133 \f
134 /* Logical datapaths and logical port numbers. */
135
136 /* A logical datapath.
137  *
138  * 'uuid' is the UUID that represents the logical datapath in the OVN_SB
139  * database.
140  *
141  * 'integer' represents the logical datapath as an integer value that is unique
142  * only within the local hypervisor.  Because of its size, this value is more
143  * practical for use in an OpenFlow flow table than a UUID.
144  *
145  * 'ports' maps 'logical_port' names to 'tunnel_key' values in the OVN_SB
146  * Port_Binding table within the logical datapath. */
147 struct logical_datapath {
148     struct hmap_node hmap_node; /* Indexed on 'uuid'. */
149     struct uuid uuid;           /* The logical_datapath's UUID. */
150     uint32_t integer;           /* Locally unique among logical datapaths. */
151     struct simap ports;         /* Logical port name to port number. */
152 };
153
154 /* Contains "struct logical_datapath"s. */
155 static struct hmap logical_datapaths = HMAP_INITIALIZER(&logical_datapaths);
156
157 /* Finds and returns the logical_datapath with the given 'uuid', or NULL if
158  * no such logical_datapath exists. */
159 static struct logical_datapath *
160 ldp_lookup(const struct uuid *uuid)
161 {
162     struct logical_datapath *ldp;
163     HMAP_FOR_EACH_IN_BUCKET (ldp, hmap_node, uuid_hash(uuid),
164                              &logical_datapaths) {
165         if (uuid_equals(&ldp->uuid, uuid)) {
166             return ldp;
167         }
168     }
169     return NULL;
170 }
171
172 /* Finds and returns the integer value corresponding to the given 'uuid', or 0
173  * if no such logical datapath exists. */
174 uint32_t
175 ldp_to_integer(const struct uuid *logical_datapath)
176 {
177     const struct logical_datapath *ldp = ldp_lookup(logical_datapath);
178     return ldp ? ldp->integer : 0;
179 }
180
181 /* Creates a new logical_datapath with the given 'uuid'. */
182 static struct logical_datapath *
183 ldp_create(const struct uuid *uuid)
184 {
185     static uint32_t next_integer = 1;
186     struct logical_datapath *ldp;
187
188     /* We don't handle the case where the logical datapaths wrap around. */
189     ovs_assert(next_integer);
190
191     ldp = xmalloc(sizeof *ldp);
192     hmap_insert(&logical_datapaths, &ldp->hmap_node, uuid_hash(uuid));
193     ldp->uuid = *uuid;
194     ldp->integer = next_integer++;
195     simap_init(&ldp->ports);
196     return ldp;
197 }
198
199 static void
200 ldp_free(struct logical_datapath *ldp)
201 {
202     simap_destroy(&ldp->ports);
203     hmap_remove(&logical_datapaths, &ldp->hmap_node);
204     free(ldp);
205 }
206
207 /* Iterates through all of the records in the Port_Binding table, updating the
208  * table of logical_datapaths to match the values found in active Bindings. */
209 static void
210 ldp_run(struct controller_ctx *ctx)
211 {
212     struct logical_datapath *ldp;
213     HMAP_FOR_EACH (ldp, hmap_node, &logical_datapaths) {
214         simap_clear(&ldp->ports);
215     }
216
217     const struct sbrec_port_binding *binding;
218     SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
219         struct logical_datapath *ldp;
220
221         ldp = ldp_lookup(&binding->logical_datapath);
222         if (!ldp) {
223             ldp = ldp_create(&binding->logical_datapath);
224         }
225
226         simap_put(&ldp->ports, binding->logical_port, binding->tunnel_key);
227     }
228
229     struct logical_datapath *next_ldp;
230     HMAP_FOR_EACH_SAFE (ldp, next_ldp, hmap_node, &logical_datapaths) {
231         if (simap_is_empty(&ldp->ports)) {
232             ldp_free(ldp);
233         }
234     }
235 }
236
237 static void
238 ldp_destroy(void)
239 {
240     struct logical_datapath *ldp, *next_ldp;
241     HMAP_FOR_EACH_SAFE (ldp, next_ldp, hmap_node, &logical_datapaths) {
242         ldp_free(ldp);
243     }
244 }
245 \f
246 void
247 lflow_init(void)
248 {
249     symtab_init();
250 }
251
252 /* Translates logical flows in the Logical_Flow table in the OVN_SB database
253  * into OpenFlow flows, adding the OpenFlow flows to 'flow_table'.
254  *
255  * We put the logical flows into OpenFlow tables 16 through 47 (inclusive). */
256 void
257 lflow_run(struct controller_ctx *ctx, struct hmap *flow_table)
258 {
259     struct hmap flows = HMAP_INITIALIZER(&flows);
260     uint32_t conj_id_ofs = 1;
261
262     ldp_run(ctx);
263
264     const struct sbrec_logical_flow *lflow;
265     SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
266         /* Find the "struct logical_datapath" asssociated with this
267          * Logical_Flow row.  If there's no such struct, that must be because
268          * no logical ports are bound to that logical datapath, so there's no
269          * point in maintaining any flows for it anyway, so skip it. */
270         const struct logical_datapath *ldp;
271         ldp = ldp_lookup(&lflow->logical_datapath);
272         if (!ldp) {
273             continue;
274         }
275
276         /* Translate OVN actions into OpenFlow actions. */
277         uint64_t ofpacts_stub[64 / 8];
278         struct ofpbuf ofpacts;
279         struct expr *prereqs;
280         uint8_t next_table_id;
281         char *error;
282
283         ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
284         next_table_id = lflow->table_id < 31 ? lflow->table_id + 17 : 0;
285         error = actions_parse_string(lflow->actions, &symtab, &ldp->ports,
286                                      next_table_id, &ofpacts, &prereqs);
287         if (error) {
288             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
289             VLOG_WARN_RL(&rl, "error parsing actions \"%s\": %s",
290                          lflow->actions, error);
291             free(error);
292             continue;
293         }
294
295         /* Translate OVN match into table of OpenFlow matches. */
296         struct hmap matches;
297         struct expr *expr;
298
299         expr = expr_parse_string(lflow->match, &symtab, &error);
300         if (!error) {
301             if (prereqs) {
302                 expr = expr_combine(EXPR_T_AND, expr, prereqs);
303                 prereqs = NULL;
304             }
305             expr = expr_annotate(expr, &symtab, &error);
306         }
307         if (error) {
308             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
309             VLOG_WARN_RL(&rl, "error parsing match \"%s\": %s",
310                          lflow->match, error);
311             expr_destroy(prereqs);
312             ofpbuf_uninit(&ofpacts);
313             free(error);
314             continue;
315         }
316
317         expr = expr_simplify(expr);
318         expr = expr_normalize(expr);
319         uint32_t n_conjs = expr_to_matches(expr, &ldp->ports, &matches);
320         expr_destroy(expr);
321
322         /* Prepare the OpenFlow matches for adding to the flow table. */
323         struct expr_match *m;
324         HMAP_FOR_EACH (m, hmap_node, &matches) {
325             match_set_metadata(&m->match, htonll(ldp->integer));
326             if (m->match.wc.masks.conj_id) {
327                 m->match.flow.conj_id += conj_id_ofs;
328             }
329             if (!m->n) {
330                 ofctrl_add_flow(flow_table, lflow->table_id + 16,
331                                 lflow->priority, &m->match, &ofpacts);
332             } else {
333                 uint64_t conj_stubs[64 / 8];
334                 struct ofpbuf conj;
335
336                 ofpbuf_use_stub(&conj, conj_stubs, sizeof conj_stubs);
337                 for (int i = 0; i < m->n; i++) {
338                     const struct cls_conjunction *src = &m->conjunctions[i];
339                     struct ofpact_conjunction *dst;
340
341                     dst = ofpact_put_CONJUNCTION(&conj);
342                     dst->id = src->id + conj_id_ofs;
343                     dst->clause = src->clause;
344                     dst->n_clauses = src->n_clauses;
345                 }
346                 ofctrl_add_flow(flow_table, lflow->table_id + 16,
347                                 lflow->priority, &m->match, &conj);
348                 ofpbuf_uninit(&conj);
349             }
350         }
351
352         /* Clean up. */
353         expr_matches_destroy(&matches);
354         ofpbuf_uninit(&ofpacts);
355         conj_id_ofs += n_conjs;
356     }
357 }
358
359 void
360 lflow_destroy(void)
361 {
362     expr_symtab_destroy(&symtab);
363     ldp_destroy();
364 }