ovn: Suppport ct_mark/ct_label in lflow matches.
[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 "packets.h"
28 #include "simap.h"
29
30 VLOG_DEFINE_THIS_MODULE(lflow);
31 \f
32 /* Symbol table. */
33
34 /* Contains "struct expr_symbol"s for fields supported by OVN lflows. */
35 static struct shash symtab;
36
37 static void
38 add_logical_register(struct shash *symtab, enum mf_field_id id)
39 {
40     char name[8];
41
42     snprintf(name, sizeof name, "reg%d", id - MFF_REG0);
43     expr_symtab_add_field(symtab, name, id, NULL, false);
44 }
45
46 static void
47 symtab_init(void)
48 {
49     shash_init(&symtab);
50
51     /* Reserve a pair of registers for the logical inport and outport.  A full
52      * 32-bit register each is bigger than we need, but the expression code
53      * doesn't yet support string fields that occupy less than a full OXM. */
54     expr_symtab_add_string(&symtab, "inport", MFF_LOG_INPORT, NULL);
55     expr_symtab_add_string(&symtab, "outport", MFF_LOG_OUTPORT, NULL);
56
57     /* Logical registers. */
58 #define MFF_LOG_REG(ID) add_logical_register(&symtab, ID);
59     MFF_LOG_REGS;
60 #undef MFF_LOG_REG
61
62     /* Connection tracking state. */
63     expr_symtab_add_field(&symtab, "ct_mark", MFF_CT_MARK, NULL, false);
64     expr_symtab_add_field(&symtab, "ct_label", MFF_CT_LABEL, NULL, false);
65     expr_symtab_add_field(&symtab, "ct_state", MFF_CT_STATE, NULL, false);
66     char ct_state_str[16];
67     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_TRACKED_BIT);
68     expr_symtab_add_predicate(&symtab, "ct.trk", ct_state_str);
69     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_NEW_BIT);
70     expr_symtab_add_subfield(&symtab, "ct.new", "ct.trk", ct_state_str);
71     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_ESTABLISHED_BIT);
72     expr_symtab_add_subfield(&symtab, "ct.est", "ct.trk", ct_state_str);
73     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_RELATED_BIT);
74     expr_symtab_add_subfield(&symtab, "ct.rel", "ct.trk", ct_state_str);
75     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_REPLY_DIR_BIT);
76     expr_symtab_add_subfield(&symtab, "ct.rpl", "ct.trk", ct_state_str);
77     snprintf(ct_state_str, sizeof ct_state_str, "ct_state[%d]", CS_INVALID_BIT);
78     expr_symtab_add_subfield(&symtab, "ct.inv", "ct.trk", ct_state_str);
79
80     /* Data fields. */
81     expr_symtab_add_field(&symtab, "eth.src", MFF_ETH_SRC, NULL, false);
82     expr_symtab_add_field(&symtab, "eth.dst", MFF_ETH_DST, NULL, false);
83     expr_symtab_add_field(&symtab, "eth.type", MFF_ETH_TYPE, NULL, true);
84     expr_symtab_add_predicate(&symtab, "eth.bcast",
85                               "eth.dst == ff:ff:ff:ff:ff:ff");
86     expr_symtab_add_subfield(&symtab, "eth.mcast", NULL, "eth.dst[40]");
87
88     expr_symtab_add_field(&symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false);
89     expr_symtab_add_predicate(&symtab, "vlan.present", "vlan.tci[12]");
90     expr_symtab_add_subfield(&symtab, "vlan.pcp", "vlan.present",
91                              "vlan.tci[13..15]");
92     expr_symtab_add_subfield(&symtab, "vlan.vid", "vlan.present",
93                              "vlan.tci[0..11]");
94
95     expr_symtab_add_predicate(&symtab, "ip4", "eth.type == 0x800");
96     expr_symtab_add_predicate(&symtab, "ip6", "eth.type == 0x86dd");
97     expr_symtab_add_predicate(&symtab, "ip", "ip4 || ip6");
98     expr_symtab_add_field(&symtab, "ip.proto", MFF_IP_PROTO, "ip", true);
99     expr_symtab_add_field(&symtab, "ip.dscp", MFF_IP_DSCP, "ip", false);
100     expr_symtab_add_field(&symtab, "ip.ecn", MFF_IP_ECN, "ip", false);
101     expr_symtab_add_field(&symtab, "ip.ttl", MFF_IP_TTL, "ip", false);
102
103     expr_symtab_add_field(&symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false);
104     expr_symtab_add_field(&symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false);
105     expr_symtab_add_predicate(&symtab, "ip4.mcast", "ip4.dst[28..31] == 0xe");
106
107     expr_symtab_add_predicate(&symtab, "icmp4", "ip4 && ip.proto == 1");
108     expr_symtab_add_field(&symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4",
109               false);
110     expr_symtab_add_field(&symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4",
111               false);
112
113     expr_symtab_add_field(&symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false);
114     expr_symtab_add_field(&symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false);
115     expr_symtab_add_field(&symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", false);
116
117     expr_symtab_add_predicate(&symtab, "icmp6", "ip6 && ip.proto == 58");
118     expr_symtab_add_field(&symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6",
119                           true);
120     expr_symtab_add_field(&symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6",
121                           true);
122
123     expr_symtab_add_predicate(&symtab, "icmp", "icmp4 || icmp6");
124
125     expr_symtab_add_field(&symtab, "ip.frag", MFF_IP_FRAG, "ip", false);
126     expr_symtab_add_predicate(&symtab, "ip.is_frag", "ip.frag[0]");
127     expr_symtab_add_predicate(&symtab, "ip.later_frag", "ip.frag[1]");
128     expr_symtab_add_predicate(&symtab, "ip.first_frag",
129                               "ip.is_frag && !ip.later_frag");
130
131     expr_symtab_add_predicate(&symtab, "arp", "eth.type == 0x806");
132     expr_symtab_add_field(&symtab, "arp.op", MFF_ARP_OP, "arp", false);
133     expr_symtab_add_field(&symtab, "arp.spa", MFF_ARP_SPA, "arp", false);
134     expr_symtab_add_field(&symtab, "arp.sha", MFF_ARP_SHA, "arp", false);
135     expr_symtab_add_field(&symtab, "arp.tpa", MFF_ARP_TPA, "arp", false);
136     expr_symtab_add_field(&symtab, "arp.tha", MFF_ARP_THA, "arp", false);
137
138     expr_symtab_add_predicate(&symtab, "nd",
139                               "icmp6.type == {135, 136} && icmp6.code == 0");
140     expr_symtab_add_field(&symtab, "nd.target", MFF_ND_TARGET, "nd", false);
141     expr_symtab_add_field(&symtab, "nd.sll", MFF_ND_SLL,
142               "nd && icmp6.type == 135", false);
143     expr_symtab_add_field(&symtab, "nd.tll", MFF_ND_TLL,
144               "nd && icmp6.type == 136", false);
145
146     expr_symtab_add_predicate(&symtab, "tcp", "ip.proto == 6");
147     expr_symtab_add_field(&symtab, "tcp.src", MFF_TCP_SRC, "tcp", false);
148     expr_symtab_add_field(&symtab, "tcp.dst", MFF_TCP_DST, "tcp", false);
149     expr_symtab_add_field(&symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", false);
150
151     expr_symtab_add_predicate(&symtab, "udp", "ip.proto == 17");
152     expr_symtab_add_field(&symtab, "udp.src", MFF_UDP_SRC, "udp", false);
153     expr_symtab_add_field(&symtab, "udp.dst", MFF_UDP_DST, "udp", false);
154
155     expr_symtab_add_predicate(&symtab, "sctp", "ip.proto == 132");
156     expr_symtab_add_field(&symtab, "sctp.src", MFF_SCTP_SRC, "sctp", false);
157     expr_symtab_add_field(&symtab, "sctp.dst", MFF_SCTP_DST, "sctp", false);
158 }
159 \f
160 /* Logical datapaths and logical port numbers. */
161
162 enum ldp_type {
163     LDP_TYPE_ROUTER,
164     LDP_TYPE_SWITCH,
165 };
166
167 /* A logical datapath.
168  *
169  * 'ports' maps 'logical_port' names to 'tunnel_key' values in the OVN_SB
170  * Port_Binding table within the logical datapath. */
171 struct logical_datapath {
172     struct hmap_node hmap_node; /* Indexed on 'uuid'. */
173     struct uuid uuid;           /* UUID from Datapath_Binding row. */
174     uint32_t tunnel_key;        /* 'tunnel_key' from Datapath_Binding row. */
175     struct simap ports;         /* Logical port name to port number. */
176     enum ldp_type type;         /* Type of logical datapath */
177 };
178
179 /* Contains "struct logical_datapath"s. */
180 static struct hmap logical_datapaths = HMAP_INITIALIZER(&logical_datapaths);
181
182 /* Finds and returns the logical_datapath for 'binding', or NULL if no such
183  * logical_datapath exists. */
184 static struct logical_datapath *
185 ldp_lookup(const struct sbrec_datapath_binding *binding)
186 {
187     struct logical_datapath *ldp;
188     HMAP_FOR_EACH_IN_BUCKET (ldp, hmap_node, uuid_hash(&binding->header_.uuid),
189                              &logical_datapaths) {
190         if (uuid_equals(&ldp->uuid, &binding->header_.uuid)) {
191             return ldp;
192         }
193     }
194     return NULL;
195 }
196
197 /* Creates a new logical_datapath for the given 'binding'. */
198 static struct logical_datapath *
199 ldp_create(const struct sbrec_datapath_binding *binding)
200 {
201     struct logical_datapath *ldp;
202
203     ldp = xmalloc(sizeof *ldp);
204     hmap_insert(&logical_datapaths, &ldp->hmap_node,
205                 uuid_hash(&binding->header_.uuid));
206     ldp->uuid = binding->header_.uuid;
207     ldp->tunnel_key = binding->tunnel_key;
208     const char *ls = smap_get(&binding->external_ids, "logical-switch");
209     ldp->type = ls ? LDP_TYPE_SWITCH : LDP_TYPE_ROUTER;
210     simap_init(&ldp->ports);
211     return ldp;
212 }
213
214 static struct logical_datapath *
215 ldp_lookup_or_create(const struct sbrec_datapath_binding *binding)
216 {
217     struct logical_datapath *ldp = ldp_lookup(binding);
218     return ldp ? ldp : ldp_create(binding);
219 }
220
221 static void
222 ldp_free(struct logical_datapath *ldp)
223 {
224     simap_destroy(&ldp->ports);
225     hmap_remove(&logical_datapaths, &ldp->hmap_node);
226     free(ldp);
227 }
228
229 /* Iterates through all of the records in the Port_Binding table, updating the
230  * table of logical_datapaths to match the values found in active
231  * Port_Bindings. */
232 static void
233 ldp_run(struct controller_ctx *ctx)
234 {
235     struct logical_datapath *ldp;
236     HMAP_FOR_EACH (ldp, hmap_node, &logical_datapaths) {
237         simap_clear(&ldp->ports);
238     }
239
240     const struct sbrec_port_binding *binding;
241     SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
242         struct logical_datapath *ldp = ldp_lookup_or_create(binding->datapath);
243
244         simap_put(&ldp->ports, binding->logical_port, binding->tunnel_key);
245     }
246
247     const struct sbrec_multicast_group *mc;
248     SBREC_MULTICAST_GROUP_FOR_EACH (mc, ctx->ovnsb_idl) {
249         struct logical_datapath *ldp = ldp_lookup_or_create(mc->datapath);
250         simap_put(&ldp->ports, mc->name, mc->tunnel_key);
251     }
252
253     struct logical_datapath *next_ldp;
254     HMAP_FOR_EACH_SAFE (ldp, next_ldp, hmap_node, &logical_datapaths) {
255         if (simap_is_empty(&ldp->ports)) {
256             ldp_free(ldp);
257         }
258     }
259 }
260
261 static void
262 ldp_destroy(void)
263 {
264     struct logical_datapath *ldp, *next_ldp;
265     HMAP_FOR_EACH_SAFE (ldp, next_ldp, hmap_node, &logical_datapaths) {
266         ldp_free(ldp);
267     }
268 }
269 \f
270 void
271 lflow_init(void)
272 {
273     symtab_init();
274 }
275
276 /* Translates logical flows in the Logical_Flow table in the OVN_SB database
277  * into OpenFlow flows.  See ovn-architecture(7) for more information. */
278 void
279 lflow_run(struct controller_ctx *ctx, struct hmap *flow_table,
280           const struct simap *ct_zones,
281           struct hmap *local_datapaths)
282 {
283     struct hmap flows = HMAP_INITIALIZER(&flows);
284     uint32_t conj_id_ofs = 1;
285
286     ldp_run(ctx);
287
288     const struct sbrec_logical_flow *lflow;
289     SBREC_LOGICAL_FLOW_FOR_EACH (lflow, ctx->ovnsb_idl) {
290         /* Find the "struct logical_datapath" associated with this
291          * Logical_Flow row.  If there's no such struct, that must be because
292          * no logical ports are bound to that logical datapath, so there's no
293          * point in maintaining any flows for it anyway, so skip it. */
294         const struct logical_datapath *ldp;
295         ldp = ldp_lookup(lflow->logical_datapath);
296         if (!ldp) {
297             continue;
298         }
299
300         bool ingress = !strcmp(lflow->pipeline, "ingress");
301
302         if (ldp->type == LDP_TYPE_SWITCH && !ingress) {
303             /* For a logical switch datapath, local_datapaths tells us if there
304              * are any local ports for this datapath.  If not, processing
305              * logical flows for the egress pipeline of this datapath is
306              * unnecessary.
307              *
308              * We still need the ingress pipeline because even if there are no
309              * local ports, we still may need to execute the ingress pipeline
310              * after a packet leaves a logical router.  Further optimization
311              * is possible, but not based on what we know with local_datapaths
312              * right now.
313              *
314              * A better approach would be a kind of "flood fill" algorithm:
315              *
316              *   1. Initialize set S to the logical datapaths that have a port
317              *      located on the hypervisor.
318              *
319              *   2. For each patch port P in a logical datapath in S, add the
320              *      logical datapath of the remote end of P to S.  Iterate
321              *      until S reaches a fixed point.
322              */
323
324             struct hmap_node *ld;
325             ld = hmap_first_with_hash(local_datapaths, ldp->tunnel_key);
326             if (!ld) {
327                 continue;
328             }
329         }
330
331         /* Determine translation of logical table IDs to physical table IDs. */
332         uint8_t first_ptable = (ingress
333                                 ? OFTABLE_LOG_INGRESS_PIPELINE
334                                 : OFTABLE_LOG_EGRESS_PIPELINE);
335         uint8_t ptable = first_ptable + lflow->table_id;
336         uint8_t output_ptable = (ingress
337                                  ? OFTABLE_REMOTE_OUTPUT
338                                  : OFTABLE_LOG_TO_PHY);
339
340         /* Translate OVN actions into OpenFlow actions.
341          *
342          * XXX Deny changes to 'outport' in egress pipeline. */
343         uint64_t ofpacts_stub[64 / 8];
344         struct ofpbuf ofpacts;
345         struct expr *prereqs;
346         char *error;
347
348         ofpbuf_use_stub(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
349         struct action_params ap = {
350             .symtab = &symtab,
351             .ports = &ldp->ports,
352             .ct_zones = ct_zones,
353
354             .n_tables = LOG_PIPELINE_LEN,
355             .first_ptable = first_ptable,
356             .cur_ltable = lflow->table_id,
357             .output_ptable = output_ptable,
358         };
359         error = actions_parse_string(lflow->actions, &ap, &ofpacts, &prereqs);
360         if (error) {
361             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
362             VLOG_WARN_RL(&rl, "error parsing actions \"%s\": %s",
363                          lflow->actions, error);
364             free(error);
365             continue;
366         }
367
368         /* Translate OVN match into table of OpenFlow matches. */
369         struct hmap matches;
370         struct expr *expr;
371
372         expr = expr_parse_string(lflow->match, &symtab, &error);
373         if (!error) {
374             if (prereqs) {
375                 expr = expr_combine(EXPR_T_AND, expr, prereqs);
376                 prereqs = NULL;
377             }
378             expr = expr_annotate(expr, &symtab, &error);
379         }
380         if (error) {
381             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
382             VLOG_WARN_RL(&rl, "error parsing match \"%s\": %s",
383                          lflow->match, error);
384             expr_destroy(prereqs);
385             ofpbuf_uninit(&ofpacts);
386             free(error);
387             continue;
388         }
389
390         expr = expr_simplify(expr);
391         expr = expr_normalize(expr);
392         uint32_t n_conjs = expr_to_matches(expr, &ldp->ports, &matches);
393         expr_destroy(expr);
394
395         /* Prepare the OpenFlow matches for adding to the flow table. */
396         struct expr_match *m;
397         HMAP_FOR_EACH (m, hmap_node, &matches) {
398             match_set_metadata(&m->match, htonll(ldp->tunnel_key));
399             if (m->match.wc.masks.conj_id) {
400                 m->match.flow.conj_id += conj_id_ofs;
401             }
402             if (!m->n) {
403                 ofctrl_add_flow(flow_table, ptable, lflow->priority,
404                                 &m->match, &ofpacts);
405             } else {
406                 uint64_t conj_stubs[64 / 8];
407                 struct ofpbuf conj;
408
409                 ofpbuf_use_stub(&conj, conj_stubs, sizeof conj_stubs);
410                 for (int i = 0; i < m->n; i++) {
411                     const struct cls_conjunction *src = &m->conjunctions[i];
412                     struct ofpact_conjunction *dst;
413
414                     dst = ofpact_put_CONJUNCTION(&conj);
415                     dst->id = src->id + conj_id_ofs;
416                     dst->clause = src->clause;
417                     dst->n_clauses = src->n_clauses;
418                 }
419                 ofctrl_add_flow(flow_table, ptable, lflow->priority,
420                                 &m->match, &conj);
421                 ofpbuf_uninit(&conj);
422             }
423         }
424
425         /* Clean up. */
426         expr_matches_destroy(&matches);
427         ofpbuf_uninit(&ofpacts);
428         conj_id_ofs += n_conjs;
429     }
430 }
431
432 void
433 lflow_destroy(void)
434 {
435     expr_symtab_destroy(&symtab);
436     ldp_destroy();
437 }