Implement OpenFlow 1.4+ OFPMP_TABLE_DESC message.
[cascardo/ovs.git] / ovn / controller / ofctrl.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 "ofctrl.h"
18 #include "dirs.h"
19 #include "dynamic-string.h"
20 #include "hmap.h"
21 #include "match.h"
22 #include "ofp-actions.h"
23 #include "ofp-msgs.h"
24 #include "ofp-print.h"
25 #include "ofp-util.h"
26 #include "ofpbuf.h"
27 #include "openflow/openflow.h"
28 #include "openvswitch/vlog.h"
29 #include "ovn-controller.h"
30 #include "rconn.h"
31 #include "socket-util.h"
32
33 VLOG_DEFINE_THIS_MODULE(ofctrl);
34
35 /* An OpenFlow flow. */
36 struct ovn_flow {
37     /* Key. */
38     struct hmap_node hmap_node; /* In 'desired_flows' or 'installed_flows'. */
39     uint8_t table_id;
40     uint16_t priority;
41     struct match match;
42
43     /* Data. */
44     struct ofpact *ofpacts;
45     size_t ofpacts_len;
46 };
47
48 static uint32_t ovn_flow_hash(const struct ovn_flow *);
49 static struct ovn_flow *ovn_flow_lookup(struct hmap *flow_table,
50                                         const struct ovn_flow *target);
51 static char *ovn_flow_to_string(const struct ovn_flow *);
52 static void ovn_flow_log(const struct ovn_flow *, const char *action);
53 static void ovn_flow_destroy(struct ovn_flow *);
54
55 /* OpenFlow connection to the switch. */
56 static struct rconn *swconn;
57
58 /* Last seen sequence number for 'swconn'.  When this differs from
59  * rconn_get_connection_seqno(rconn), 'swconn' has reconnected. */
60 static unsigned int seqno;
61
62 /* Counter for in-flight OpenFlow messages on 'swconn'.  We only send a new
63  * round of flow table modifications to the switch when the counter falls to
64  * zero, to avoid unbounded buffering. */
65 static struct rconn_packet_counter *tx_counter;
66
67 /* Flow tables.  Each holds "struct ovn_flow"s.
68  *
69  * 'desired_flows' is the flow table that we want the switch to have.
70  * 'installed_flows' is the flow table currently installed in the switch. */
71 static struct hmap desired_flows;
72 static struct hmap installed_flows;
73
74 static void ovn_flow_table_clear(struct hmap *flow_table);
75 static void ovn_flow_table_destroy(struct hmap *flow_table);
76
77 static void ofctrl_update_flows(void);
78 static void ofctrl_recv(const struct ofpbuf *msg);
79
80 void
81 ofctrl_init(void)
82 {
83     swconn = rconn_create(5, 0, DSCP_DEFAULT, 1 << OFP13_VERSION);
84     tx_counter = rconn_packet_counter_create();
85     hmap_init(&desired_flows);
86     hmap_init(&installed_flows);
87 }
88
89 /* This function should be called in the main loop after anything that updates
90  * the flow table (e.g. after calls to ofctrl_clear_flows() and
91  * ofctrl_add_flow()). */
92 void
93 ofctrl_run(struct controller_ctx *ctx)
94 {
95     char *target;
96     target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), ctx->br_int_name);
97     if (strcmp(target, rconn_get_target(swconn))) {
98         rconn_connect(swconn, target, target);
99     }
100     free(target);
101
102     rconn_run(swconn);
103
104     if (!rconn_is_connected(swconn)) {
105         return;
106     }
107     if (!rconn_packet_counter_n_packets(tx_counter)) {
108         ofctrl_update_flows();
109     }
110
111     for (int i = 0; i < 50; i++) {
112         struct ofpbuf *msg = rconn_recv(swconn);
113         if (!msg) {
114             break;
115         }
116
117         ofctrl_recv(msg);
118         ofpbuf_delete(msg);
119     }
120 }
121
122 void
123 ofctrl_wait(void)
124 {
125     rconn_run_wait(swconn);
126     rconn_recv_wait(swconn);
127 }
128
129 void
130 ofctrl_destroy(void)
131 {
132     rconn_destroy(swconn);
133     ovn_flow_table_destroy(&installed_flows);
134     ovn_flow_table_destroy(&desired_flows);
135     rconn_packet_counter_destroy(tx_counter);
136 }
137 \f
138 static void
139 queue_msg(struct ofpbuf *msg)
140 {
141     rconn_send(swconn, msg, tx_counter);
142 }
143
144 static void
145 ofctrl_recv(const struct ofpbuf *msg)
146 {
147     enum ofptype type;
148     struct ofpbuf b;
149
150     b = *msg;
151     if (ofptype_pull(&type, &b)) {
152         return;
153     }
154
155     switch (type) {
156     case OFPTYPE_ECHO_REQUEST:
157         queue_msg(make_echo_reply(msg->data));
158         break;
159
160     case OFPTYPE_ECHO_REPLY:
161     case OFPTYPE_PACKET_IN:
162     case OFPTYPE_PORT_STATUS:
163     case OFPTYPE_FLOW_REMOVED:
164         /* Nothing to do. */
165         break;
166
167     case OFPTYPE_HELLO:
168     case OFPTYPE_ERROR:
169     case OFPTYPE_FEATURES_REQUEST:
170     case OFPTYPE_FEATURES_REPLY:
171     case OFPTYPE_GET_CONFIG_REQUEST:
172     case OFPTYPE_GET_CONFIG_REPLY:
173     case OFPTYPE_SET_CONFIG:
174     case OFPTYPE_PACKET_OUT:
175     case OFPTYPE_FLOW_MOD:
176     case OFPTYPE_GROUP_MOD:
177     case OFPTYPE_PORT_MOD:
178     case OFPTYPE_TABLE_MOD:
179     case OFPTYPE_BARRIER_REQUEST:
180     case OFPTYPE_BARRIER_REPLY:
181     case OFPTYPE_QUEUE_GET_CONFIG_REQUEST:
182     case OFPTYPE_QUEUE_GET_CONFIG_REPLY:
183     case OFPTYPE_DESC_STATS_REQUEST:
184     case OFPTYPE_DESC_STATS_REPLY:
185     case OFPTYPE_FLOW_STATS_REQUEST:
186     case OFPTYPE_FLOW_STATS_REPLY:
187     case OFPTYPE_AGGREGATE_STATS_REQUEST:
188     case OFPTYPE_AGGREGATE_STATS_REPLY:
189     case OFPTYPE_TABLE_STATS_REQUEST:
190     case OFPTYPE_TABLE_STATS_REPLY:
191     case OFPTYPE_PORT_STATS_REQUEST:
192     case OFPTYPE_PORT_STATS_REPLY:
193     case OFPTYPE_QUEUE_STATS_REQUEST:
194     case OFPTYPE_QUEUE_STATS_REPLY:
195     case OFPTYPE_PORT_DESC_STATS_REQUEST:
196     case OFPTYPE_PORT_DESC_STATS_REPLY:
197     case OFPTYPE_ROLE_REQUEST:
198     case OFPTYPE_ROLE_REPLY:
199     case OFPTYPE_ROLE_STATUS:
200     case OFPTYPE_SET_FLOW_FORMAT:
201     case OFPTYPE_FLOW_MOD_TABLE_ID:
202     case OFPTYPE_SET_PACKET_IN_FORMAT:
203     case OFPTYPE_FLOW_AGE:
204     case OFPTYPE_SET_CONTROLLER_ID:
205     case OFPTYPE_FLOW_MONITOR_STATS_REQUEST:
206     case OFPTYPE_FLOW_MONITOR_STATS_REPLY:
207     case OFPTYPE_FLOW_MONITOR_CANCEL:
208     case OFPTYPE_FLOW_MONITOR_PAUSED:
209     case OFPTYPE_FLOW_MONITOR_RESUMED:
210     case OFPTYPE_GET_ASYNC_REQUEST:
211     case OFPTYPE_GET_ASYNC_REPLY:
212     case OFPTYPE_SET_ASYNC_CONFIG:
213     case OFPTYPE_METER_MOD:
214     case OFPTYPE_GROUP_STATS_REQUEST:
215     case OFPTYPE_GROUP_STATS_REPLY:
216     case OFPTYPE_GROUP_DESC_STATS_REQUEST:
217     case OFPTYPE_GROUP_DESC_STATS_REPLY:
218     case OFPTYPE_GROUP_FEATURES_STATS_REQUEST:
219     case OFPTYPE_GROUP_FEATURES_STATS_REPLY:
220     case OFPTYPE_METER_STATS_REQUEST:
221     case OFPTYPE_METER_STATS_REPLY:
222     case OFPTYPE_METER_CONFIG_STATS_REQUEST:
223     case OFPTYPE_METER_CONFIG_STATS_REPLY:
224     case OFPTYPE_METER_FEATURES_STATS_REQUEST:
225     case OFPTYPE_METER_FEATURES_STATS_REPLY:
226     case OFPTYPE_TABLE_FEATURES_STATS_REQUEST:
227     case OFPTYPE_TABLE_FEATURES_STATS_REPLY:
228     case OFPTYPE_TABLE_DESC_REQUEST:
229     case OFPTYPE_TABLE_DESC_REPLY:
230     case OFPTYPE_BUNDLE_CONTROL:
231     case OFPTYPE_BUNDLE_ADD_MESSAGE:
232     case OFPTYPE_NXT_GENEVE_TABLE_MOD:
233     case OFPTYPE_NXT_GENEVE_TABLE_REQUEST:
234     case OFPTYPE_NXT_GENEVE_TABLE_REPLY:
235     default:
236         /* Messages that are generally unexpected. */
237         if (VLOG_IS_DBG_ENABLED()) {
238             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(30, 300);
239
240             char *s = ofp_to_string(msg->data, msg->size, 2);
241             VLOG_DBG_RL(&rl, "OpenFlow packet ignored: %s", s);
242             free(s);
243         }
244     }
245 }
246 \f
247 /* Flow table interface to the rest of ovn-controller. */
248
249 /* Clears the table of flows desired to be in the switch.  Call this before
250  * adding the desired flows (with ofctrl_add_flow()). */
251 void
252 ofctrl_clear_flows(void)
253 {
254     ovn_flow_table_clear(&desired_flows);
255 }
256
257 /* Adds a flow with the specified 'match' and 'actions' to the OpenFlow table
258  * numbered 'table_id' with the given 'priority'.  The caller retains ownership
259  * of 'match' and 'actions'.
260  *
261  * This just assembles the desired flow table in memory.  Nothing is actually
262  * sent to the switch until a later call to ofctrl_run(). */
263 void
264 ofctrl_add_flow(uint8_t table_id, uint16_t priority,
265                 const struct match *match, const struct ofpbuf *actions)
266 {
267     struct ovn_flow *f = xmalloc(sizeof *f);
268     f->table_id = table_id;
269     f->priority = priority;
270     f->match = *match;
271     f->ofpacts = xmemdup(actions->data, actions->size);
272     f->ofpacts_len = actions->size;
273
274     if (ovn_flow_lookup(&desired_flows, f)) {
275         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
276         if (!VLOG_DROP_INFO(&rl)) {
277             char *s = ovn_flow_to_string(f);
278             VLOG_INFO("dropping duplicate flow: %s", s);
279             free(s);
280         }
281
282         ovn_flow_destroy(f);
283         return;
284     }
285
286     hmap_insert(&desired_flows, &f->hmap_node, ovn_flow_hash(f));
287 }
288 \f
289 /* ovn_flow. */
290
291 /* Returns a hash of the key in 'f'. */
292 static uint32_t
293 ovn_flow_hash(const struct ovn_flow *f)
294 {
295     return hash_2words((f->table_id << 16) | f->priority,
296                        match_hash(&f->match, 0));
297
298 }
299
300 /* Finds and returns an ovn_flow in 'flow_table' whose key is identical to
301  * 'target''s key, or NULL if there is none. */
302 static struct ovn_flow *
303 ovn_flow_lookup(struct hmap *flow_table, const struct ovn_flow *target)
304 {
305     struct ovn_flow *f;
306
307     HMAP_FOR_EACH_WITH_HASH (f, hmap_node, target->hmap_node.hash,
308                              flow_table) {
309         if (f->table_id == target->table_id
310             && f->priority == target->priority
311             && match_equal(&f->match, &target->match)) {
312             return f;
313         }
314     }
315     return NULL;
316 }
317
318 static char *
319 ovn_flow_to_string(const struct ovn_flow *f)
320 {
321     struct ds s = DS_EMPTY_INITIALIZER;
322     ds_put_format(&s, "table_id=%"PRIu8", ", f->table_id);
323     ds_put_format(&s, "priority=%"PRIu16", ", f->priority);
324     match_format(&f->match, &s, OFP_DEFAULT_PRIORITY);
325     ds_put_cstr(&s, ", actions=");
326     ofpacts_format(f->ofpacts, f->ofpacts_len, &s);
327     return ds_steal_cstr(&s);
328 }
329
330 static void
331 ovn_flow_log(const struct ovn_flow *f, const char *action)
332 {
333     if (VLOG_IS_DBG_ENABLED()) {
334         char *s = ovn_flow_to_string(f);
335         VLOG_DBG("%s flow: %s", action, s);
336         free(s);
337     }
338 }
339
340 static void
341 ovn_flow_destroy(struct ovn_flow *f)
342 {
343     if (f) {
344         free(f->ofpacts);
345         free(f);
346     }
347 }
348 \f
349 /* Flow tables of struct ovn_flow. */
350
351 static void
352 ovn_flow_table_clear(struct hmap *flow_table)
353 {
354     struct ovn_flow *f, *next;
355     HMAP_FOR_EACH_SAFE (f, next, hmap_node, flow_table) {
356         hmap_remove(flow_table, &f->hmap_node);
357         ovn_flow_destroy(f);
358     }
359 }
360 static void
361 ovn_flow_table_destroy(struct hmap *flow_table)
362 {
363     ovn_flow_table_clear(flow_table);
364     hmap_destroy(flow_table);
365 }
366 \f
367 /* Flow table update. */
368
369 static void
370 queue_flow_mod(struct ofputil_flow_mod *fm)
371 {
372     fm->buffer_id = UINT32_MAX;
373     fm->out_port = OFPP_ANY;
374     fm->out_group = OFPG_ANY;
375     queue_msg(ofputil_encode_flow_mod(fm, OFPUTIL_P_OF13_OXM));
376 }
377
378 static void
379 ofctrl_update_flows(void)
380 {
381     /* If we've (re)connected, don't make any assumptions about the flows in
382      * the switch: delete all of them.  (We'll immediately repopulate it
383      * below.) */
384     if (seqno != rconn_get_connection_seqno(swconn)) {
385         seqno = rconn_get_connection_seqno(swconn);
386
387         /* Send a flow_mod to delete all flows. */
388         struct ofputil_flow_mod fm = {
389             .match = MATCH_CATCHALL_INITIALIZER,
390             .table_id = OFPTT_ALL,
391             .command = OFPFC_DELETE,
392         };
393         queue_flow_mod(&fm);
394         VLOG_DBG("clearing all flows");
395
396         /* Clear installed_flows, to match the state of the switch. */
397         ovn_flow_table_clear(&installed_flows);
398     }
399
400     /* Iterate through all of the installed flows.  If any of them are no
401      * longer desired, delete them; if any of them should have different
402      * actions, update them. */
403     struct ovn_flow *i, *next;
404     HMAP_FOR_EACH_SAFE (i, next, hmap_node, &installed_flows) {
405         struct ovn_flow *d = ovn_flow_lookup(&desired_flows, i);
406         if (!d) {
407             /* Installed flow is no longer desirable.  Delete it from the
408              * switch and from installed_flows. */
409             struct ofputil_flow_mod fm;
410             memset(&fm, 0, sizeof fm);
411             fm.match = i->match;
412             fm.priority = i->priority;
413             fm.table_id = i->table_id;
414             fm.command = OFPFC_DELETE_STRICT;
415             queue_flow_mod(&fm);
416             ovn_flow_log(i, "removing");
417
418             hmap_remove(&installed_flows, &i->hmap_node);
419             ovn_flow_destroy(i);
420         } else {
421             if (!ofpacts_equal(i->ofpacts, i->ofpacts_len,
422                                d->ofpacts, d->ofpacts_len)) {
423                 /* Update actions in installed flow. */
424                 struct ofputil_flow_mod fm;
425                 memset(&fm, 0, sizeof fm);
426                 fm.match = i->match;
427                 fm.priority = i->priority;
428                 fm.table_id = i->table_id;
429                 fm.ofpacts = d->ofpacts;
430                 fm.ofpacts_len = d->ofpacts_len;
431                 fm.command = OFPFC_MODIFY_STRICT;
432                 queue_flow_mod(&fm);
433                 ovn_flow_log(i, "updating");
434
435                 /* Replace 'i''s actions by 'd''s. */
436                 free(i->ofpacts);
437                 i->ofpacts = d->ofpacts;
438                 i->ofpacts_len = d->ofpacts_len;
439                 d->ofpacts = NULL;
440                 d->ofpacts_len = 0;
441             }
442
443             hmap_remove(&desired_flows, &d->hmap_node);
444             ovn_flow_destroy(d);
445         }
446     }
447
448     /* The previous loop removed from desired_flows all of the flows that are
449      * already installed.  Thus, any flows remaining in desired_flows need to
450      * be added to the flow table. */
451     struct ovn_flow *d;
452     HMAP_FOR_EACH_SAFE (d, next, hmap_node, &desired_flows) {
453         /* Send flow_mod to add flow. */
454         struct ofputil_flow_mod fm;
455         memset(&fm, 0, sizeof fm);
456         fm.match = d->match;
457         fm.priority = d->priority;
458         fm.table_id = d->table_id;
459         fm.ofpacts = d->ofpacts;
460         fm.ofpacts_len = d->ofpacts_len;
461         fm.command = OFPFC_ADD;
462         queue_flow_mod(&fm);
463         ovn_flow_log(d, "adding");
464
465         /* Move 'd' from desired_flows to installed_flows. */
466         hmap_remove(&desired_flows, &d->hmap_node);
467         hmap_insert(&installed_flows, &d->hmap_node, d->hmap_node.hash);
468     }
469 }