Merge citrix branch into master.
[sliver-openvswitch.git] / ofproto / in-band.c
1 /*
2  * Copyright (c) 2008, 2009 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 #include "in-band.h"
19 #include <arpa/inet.h>
20 #include <errno.h>
21 #include <inttypes.h>
22 #include <net/if.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "dhcp.h"
26 #include "dpif.h"
27 #include "flow.h"
28 #include "mac-learning.h"
29 #include "netdev.h"
30 #include "odp-util.h"
31 #include "ofp-print.h"
32 #include "ofproto.h"
33 #include "ofpbuf.h"
34 #include "openflow/openflow.h"
35 #include "openvswitch/datapath-protocol.h"
36 #include "packets.h"
37 #include "poll-loop.h"
38 #include "rconn.h"
39 #include "status.h"
40 #include "timeval.h"
41 #include "vconn.h"
42
43 #define THIS_MODULE VLM_in_band
44 #include "vlog.h"
45
46 /* In-band control allows a single network to be used for OpenFlow
47  * traffic and other data traffic.  Refer to ovs-vswitchd.conf(5) and 
48  * secchan(8) for a description of configuring in-band control.
49  *
50  * This comment is an attempt to describe how in-band control works at a
51  * wire- and implementation-level.  Correctly implementing in-band
52  * control has proven difficult due to its many subtleties, and has thus
53  * gone through many iterations.  Please read through and understand the
54  * reasoning behind the chosen rules before making modifications.
55  *
56  * In Open vSwitch, in-band control is implemented as "hidden" flows (in
57  * that they are not visible through OpenFlow) and at a higher priority
58  * than wildcarded flows can be setup by the controller.  This is done 
59  * so that the controller cannot interfere with them and possibly break 
60  * connectivity with its switches.  It is possible to see all flows, 
61  * including in-band ones, with the ovs-appctl "bridge/dump-flows" 
62  * command.
63  *
64  * The following rules are always enabled with the "normal" action by a 
65  * switch with in-band control:
66  *
67  *    a. DHCP requests sent from the local port.
68  *    b. ARP replies to the local port's MAC address.
69  *    c. ARP requests from the local port's MAC address.
70  *    d. ARP replies to the remote side's MAC address.  Note that the 
71  *       remote side is either the controller or the gateway to reach 
72  *       the controller.
73  *    e. ARP requests from the remote side's MAC address.  Note that
74  *       like (d), the MAC is either for the controller or gateway.
75  *    f. ARP replies containing the controller's IP address as a target.
76  *    g. ARP requests containing the controller's IP address as a source.
77  *    h. OpenFlow (6633/tcp) traffic to the controller's IP.
78  *    i. OpenFlow (6633/tcp) traffic from the controller's IP.
79  *
80  * The goal of these rules is to be as narrow as possible to allow a
81  * switch to join a network and be able to communicate with a
82  * controller.  As mentioned earlier, these rules have higher priority
83  * than the controller's rules, so if they are too broad, they may 
84  * prevent the controller from implementing its policy.  As such,
85  * in-band actively monitors some aspects of flow and packet processing
86  * so that the rules can be made more precise.
87  *
88  * In-band control monitors attempts to add flows into the datapath that
89  * could interfere with its duties.  The datapath only allows exact
90  * match entries, so in-band control is able to be very precise about
91  * the flows it prevents.  Flows that miss in the datapath are sent to
92  * userspace to be processed, so preventing these flows from being
93  * cached in the "fast path" does not affect correctness.  The only type 
94  * of flow that is currently prevented is one that would prevent DHCP 
95  * replies from being seen by the local port.  For example, a rule that 
96  * forwarded all DHCP traffic to the controller would not be allowed, 
97  * but one that forwarded to all ports (including the local port) would.
98  *
99  * As mentioned earlier, packets that miss in the datapath are sent to
100  * the userspace for processing.  The userspace has its own flow table,
101  * the "classifier", so in-band checks whether any special processing 
102  * is needed before the classifier is consulted.  If a packet is a DHCP 
103  * response to a request from the local port, the packet is forwarded to 
104  * the local port, regardless of the flow table.  Note that this requires 
105  * L7 processing of DHCP replies to determine whether the 'chaddr' field 
106  * matches the MAC address of the local port.
107  *
108  * It is interesting to note that for an L3-based in-band control
109  * mechanism, the majority of rules are devoted to ARP traffic.  At first 
110  * glance, some of these rules appear redundant.  However, each serves an 
111  * important role.  First, in order to determine the MAC address of the 
112  * remote side (controller or gateway) for other ARP rules, we must allow 
113  * ARP traffic for our local port with rules (b) and (c).  If we are 
114  * between a switch and its connection to the controller, we have to 
115  * allow the other switch's ARP traffic to through.  This is done with 
116  * rules (d) and (e), since we do not know the addresses of the other
117  * switches a priori, but do know the controller's or gateway's.  Finally, 
118  * if the controller is running in a local guest VM that is not reached 
119  * through the local port, the switch that is connected to the VM must 
120  * allow ARP traffic based on the controller's IP address, since it will 
121  * not know the MAC address of the local port that is sending the traffic 
122  * or the MAC address of the controller in the guest VM.
123  *
124  * With a few notable exceptions below, in-band should work in most
125  * network setups.  The following are considered "supported' in the
126  * current implementation: 
127  *
128  *    - Locally Connected.  The switch and controller are on the same
129  *      subnet.  This uses rules (a), (b), (c), (h), and (i).
130  *
131  *    - Reached through Gateway.  The switch and controller are on
132  *      different subnets and must go through a gateway.  This uses
133  *      rules (a), (b), (c), (h), and (i).
134  *
135  *    - Between Switch and Controller.  This switch is between another
136  *      switch and the controller, and we want to allow the other
137  *      switch's traffic through.  This uses rules (d), (e), (h), and
138  *      (i).  It uses (b) and (c) indirectly in order to know the MAC
139  *      address for rules (d) and (e).  Note that DHCP for the other
140  *      switch will not work unless the controller explicitly lets this 
141  *      switch pass the traffic.
142  *
143  *    - Between Switch and Gateway.  This switch is between another
144  *      switch and the gateway, and we want to allow the other switch's
145  *      traffic through.  This uses the same rules and logic as the
146  *      "Between Switch and Controller" configuration described earlier.
147  *
148  *    - Controller on Local VM.  The controller is a guest VM on the
149  *      system running in-band control.  This uses rules (a), (b), (c), 
150  *      (h), and (i).
151  *
152  *    - Controller on Local VM with Different Networks.  The controller
153  *      is a guest VM on the system running in-band control, but the
154  *      local port is not used to connect to the controller.  For
155  *      example, an IP address is configured on eth0 of the switch.  The
156  *      controller's VM is connected through eth1 of the switch, but an
157  *      IP address has not been configured for that port on the switch.
158  *      As such, the switch will use eth0 to connect to the controller,
159  *      and eth1's rules about the local port will not work.  In the
160  *      example, the switch attached to eth0 would use rules (a), (b), 
161  *      (c), (h), and (i) on eth0.  The switch attached to eth1 would use 
162  *      rules (f), (g), (h), and (i).
163  *
164  * The following are explicitly *not* supported by in-band control:
165  *
166  *    - Specify Controller by Name.  Currently, the controller must be 
167  *      identified by IP address.  A naive approach would be to permit
168  *      all DNS traffic.  Unfortunately, this would prevent the
169  *      controller from defining any policy over DNS.  Since switches
170  *      that are located behind us need to connect to the controller, 
171  *      in-band cannot simply add a rule that allows DNS traffic from
172  *      the local port.  The "correct" way to support this is to parse
173  *      DNS requests to allow all traffic related to a request for the
174  *      controller's name through.  Due to the potential security
175  *      problems and amount of processing, we decided to hold off for
176  *      the time-being.
177  *
178  *    - Multiple Controllers.  There is nothing intrinsic in the high-
179  *      level design that prevents using multiple (known) controllers, 
180  *      however, the current implementation's data structures assume
181  *      only one.
182  *
183  *    - Differing Controllers for Switches.  All switches must know
184  *      the L3 addresses for all the controllers that other switches 
185  *      may use, since rules need to be setup to allow traffic related 
186  *      to those controllers through.  See rules (f), (g), (h), and (i).
187  *
188  *    - Differing Routes for Switches.  In order for the switch to 
189  *      allow other switches to connect to a controller through a 
190  *      gateway, it allows the gateway's traffic through with rules (d)
191  *      and (e).  If the routes to the controller differ for the two
192  *      switches, we will not know the MAC address of the alternate 
193  *      gateway.
194  */
195
196 #define IB_BASE_PRIORITY 18181800
197
198 enum {
199     IBR_FROM_LOCAL_DHCP,          /* (a) From local port, DHCP. */
200     IBR_TO_LOCAL_ARP,             /* (b) To local port, ARP. */
201     IBR_FROM_LOCAL_ARP,           /* (c) From local port, ARP. */
202     IBR_TO_REMOTE_ARP,            /* (d) To remote MAC, ARP. */
203     IBR_FROM_REMOTE_ARP,          /* (e) From remote MAC, ARP. */
204     IBR_TO_CTL_ARP,               /* (f) To controller IP, ARP. */
205     IBR_FROM_CTL_ARP,             /* (g) From controller IP, ARP. */
206     IBR_TO_CTL_OFP,               /* (h) To controller, OpenFlow port. */
207     IBR_FROM_CTL_OFP,             /* (i) From controller, OpenFlow port. */
208 #if OFP_TCP_PORT != OFP_SSL_PORT
209 #error Need to support separate TCP and SSL flows.
210 #endif
211     N_IB_RULES
212 };
213
214 struct ib_rule {
215     bool installed;
216     flow_t flow;
217     uint32_t wildcards;
218     unsigned int priority;
219 };
220
221 struct in_band {
222     struct ofproto *ofproto;
223     struct rconn *controller;
224     struct status_category *ss_cat;
225
226     /* Keep track of local port's information. */
227     uint8_t local_mac[ETH_ADDR_LEN];       /* Current MAC. */
228     struct netdev *local_netdev;           /* Local port's network device. */
229     time_t next_local_refresh;
230
231     /* Keep track of controller and next hop's information. */
232     uint32_t controller_ip;                /* Controller IP, 0 if unknown. */
233     uint8_t remote_mac[ETH_ADDR_LEN];      /* Remote MAC. */
234     struct netdev *remote_netdev;
235     uint8_t last_remote_mac[ETH_ADDR_LEN]; /* Previous remote MAC. */
236     time_t next_remote_refresh;
237
238     /* Rules that we set up. */
239     struct ib_rule rules[N_IB_RULES];
240 };
241
242 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(60, 60);
243
244 static const uint8_t *
245 get_remote_mac(struct in_band *ib)
246 {
247     int retval;
248     bool have_mac;
249     struct in_addr c_in4;   /* Controller's IP address. */
250     struct in_addr r_in4;   /* Next hop IP address. */
251     char *next_hop_dev;
252     time_t now = time_now();
253
254     if (now >= ib->next_remote_refresh) {
255         /* Find the next-hop IP address. */
256         c_in4.s_addr = ib->controller_ip;
257         memset(ib->remote_mac, 0, sizeof ib->remote_mac);
258         retval = netdev_get_next_hop(ib->local_netdev,
259                                      &c_in4, &r_in4, &next_hop_dev);
260         if (retval) {
261             VLOG_WARN("cannot find route for controller ("IP_FMT"): %s",
262                     IP_ARGS(&ib->controller_ip), strerror(retval));
263             ib->next_remote_refresh = now + 1;
264             return NULL;
265         }
266         if (!r_in4.s_addr) {
267             r_in4.s_addr = c_in4.s_addr;
268         }
269
270         /* Get the next-hop IP and network device. */
271         if (!ib->remote_netdev
272             || strcmp(netdev_get_name(ib->remote_netdev), next_hop_dev))
273         {
274             netdev_close(ib->remote_netdev);
275             retval = netdev_open(next_hop_dev, NETDEV_ETH_TYPE_NONE,
276                                  &ib->remote_netdev);
277             if (retval) {
278                 VLOG_WARN_RL(&rl, "cannot open netdev %s (next hop "
279                              "to controller "IP_FMT"): %s",
280                              next_hop_dev, IP_ARGS(&ib->controller_ip),
281                              strerror(retval));
282                 ib->next_remote_refresh = now + 1;
283                 return NULL;
284             }
285         }
286
287         /* Look up the MAC address of the next-hop IP address. */
288         retval = netdev_arp_lookup(ib->remote_netdev, r_in4.s_addr,
289                                    ib->remote_mac);
290         if (retval) {
291             VLOG_DBG_RL(&rl, "cannot look up remote MAC address ("IP_FMT"): %s",
292                         IP_ARGS(&r_in4.s_addr), strerror(retval));
293         }
294         have_mac = !eth_addr_is_zero(ib->remote_mac);
295         free(next_hop_dev);
296         if (have_mac
297             && !eth_addr_equals(ib->last_remote_mac, ib->remote_mac)) {
298             VLOG_DBG("remote MAC address changed from "ETH_ADDR_FMT" to "
299                      ETH_ADDR_FMT,
300                      ETH_ADDR_ARGS(ib->last_remote_mac),
301                      ETH_ADDR_ARGS(ib->remote_mac));
302             memcpy(ib->last_remote_mac, ib->remote_mac, ETH_ADDR_LEN);
303         }
304
305         /* Schedule next refresh.
306          *
307          * If we have an IP address but not a MAC address, then refresh
308          * quickly, since we probably will get a MAC address soon (via ARP).
309          * Otherwise, we can afford to wait a little while. */
310         ib->next_remote_refresh 
311                 = now + (!ib->controller_ip || have_mac ? 10 : 1);
312     }
313
314     return !eth_addr_is_zero(ib->remote_mac) ? ib->remote_mac : NULL;
315 }
316
317 static const uint8_t *
318 get_local_mac(struct in_band *ib)
319 {
320     time_t now = time_now();
321     if (now >= ib->next_local_refresh) {
322         uint8_t ea[ETH_ADDR_LEN];
323         if (ib->local_netdev && !netdev_get_etheraddr(ib->local_netdev, ea)) {
324             memcpy(ib->local_mac, ea, ETH_ADDR_LEN);
325         }
326         ib->next_local_refresh = now + 1;
327     }
328     return !eth_addr_is_zero(ib->local_mac) ? ib->local_mac : NULL;
329 }
330
331 static void
332 in_band_status_cb(struct status_reply *sr, void *in_band_)
333 {
334     struct in_band *in_band = in_band_;
335
336     if (!eth_addr_is_zero(in_band->local_mac)) {
337         status_reply_put(sr, "local-mac="ETH_ADDR_FMT,
338                          ETH_ADDR_ARGS(in_band->local_mac));
339     }
340
341     if (!eth_addr_is_zero(in_band->remote_mac)) {
342         status_reply_put(sr, "remote-mac="ETH_ADDR_FMT,
343                          ETH_ADDR_ARGS(in_band->remote_mac));
344     }
345 }
346
347 static void
348 drop_flow(struct in_band *in_band, int rule_idx)
349 {
350     struct ib_rule *rule = &in_band->rules[rule_idx];
351
352     if (rule->installed) {
353         rule->installed = false;
354         ofproto_delete_flow(in_band->ofproto, &rule->flow, rule->wildcards,
355                             rule->priority);
356     }
357 }
358
359 /* out_port and fixed_fields are assumed never to change. */
360 static void
361 setup_flow(struct in_band *in_band, int rule_idx, const flow_t *flow,
362            uint32_t fixed_fields, uint16_t out_port)
363 {
364     struct ib_rule *rule = &in_band->rules[rule_idx];
365
366     if (!rule->installed || memcmp(flow, &rule->flow, sizeof *flow)) {
367         union ofp_action action;
368
369         drop_flow(in_band, rule_idx);
370
371         rule->installed = true;
372         rule->flow = *flow;
373         rule->wildcards = OFPFW_ALL & ~fixed_fields;
374         rule->priority = IB_BASE_PRIORITY + (N_IB_RULES - rule_idx);
375
376         action.type = htons(OFPAT_OUTPUT);
377         action.output.len = htons(sizeof action);
378         action.output.port = htons(out_port);
379         action.output.max_len = htons(0);
380         ofproto_add_flow(in_band->ofproto, &rule->flow, rule->wildcards,
381                          rule->priority, &action, 1, 0);
382     }
383 }
384
385 /* Returns true if 'packet' should be sent to the local port regardless
386  * of the flow table. */ 
387 bool
388 in_band_msg_in_hook(struct in_band *in_band, const flow_t *flow, 
389                     const struct ofpbuf *packet)
390 {
391     if (!in_band) {
392         return false;
393     }
394
395     /* Regardless of how the flow table is configured, we want to be
396      * able to see replies to our DHCP requests. */
397     if (flow->dl_type == htons(ETH_TYPE_IP)
398             && flow->nw_proto == IP_TYPE_UDP
399             && flow->tp_src == htons(DHCP_SERVER_PORT)
400             && flow->tp_dst == htons(DHCP_CLIENT_PORT)
401             && packet->l7) {
402         struct dhcp_header *dhcp;
403         const uint8_t *local_mac;
404
405         dhcp = ofpbuf_at(packet, (char *)packet->l7 - (char *)packet->data,
406                          sizeof *dhcp);
407         if (!dhcp) {
408             return false;
409         }
410
411         local_mac = get_local_mac(in_band);
412         if (eth_addr_equals(dhcp->chaddr, local_mac)) {
413             return true;
414         }
415     }
416
417     return false;
418 }
419
420 /* Returns true if the rule that would match 'flow' with 'actions' is 
421  * allowed to be set up in the datapath. */
422 bool
423 in_band_rule_check(struct in_band *in_band, const flow_t *flow,
424                    const struct odp_actions *actions)
425 {
426     if (!in_band) {
427         return true;
428     }
429
430     /* Don't allow flows that would prevent DHCP replies from being seen
431      * by the local port. */
432     if (flow->dl_type == htons(ETH_TYPE_IP)
433             && flow->nw_proto == IP_TYPE_UDP
434             && flow->tp_src == htons(DHCP_SERVER_PORT) 
435             && flow->tp_dst == htons(DHCP_CLIENT_PORT)) {
436         int i;
437
438         for (i=0; i<actions->n_actions; i++) {
439             if (actions->actions[i].output.type == ODPAT_OUTPUT 
440                     && actions->actions[i].output.port == ODPP_LOCAL) {
441                 return true;
442             }   
443         }
444         return false;
445     }
446
447     return true;
448 }
449
450 void
451 in_band_run(struct in_band *in_band)
452 {
453     time_t now = time_now();
454     uint32_t controller_ip;
455     const uint8_t *remote_mac;
456     const uint8_t *local_mac;
457     flow_t flow;
458
459     if (now < in_band->next_remote_refresh 
460             && now < in_band->next_local_refresh) {
461         return;
462     }
463
464     controller_ip = rconn_get_remote_ip(in_band->controller);
465     if (in_band->controller_ip && controller_ip != in_band->controller_ip) {
466         VLOG_DBG("controller IP address changed from "IP_FMT" to "IP_FMT, 
467                  IP_ARGS(&in_band->controller_ip),
468                  IP_ARGS(&controller_ip));
469     }
470     in_band->controller_ip = controller_ip;
471
472     remote_mac = get_remote_mac(in_band);
473     local_mac = get_local_mac(in_band);
474
475     if (local_mac) {
476         /* Allow DHCP requests to be sent from the local port. */
477         memset(&flow, 0, sizeof flow);
478         flow.in_port = ODPP_LOCAL;
479         flow.dl_type = htons(ETH_TYPE_IP);
480         memcpy(flow.dl_src, local_mac, ETH_ADDR_LEN);
481         flow.nw_proto = IP_TYPE_UDP;
482         flow.tp_src = htons(DHCP_CLIENT_PORT);
483         flow.tp_dst = htons(DHCP_SERVER_PORT);
484         setup_flow(in_band, IBR_FROM_LOCAL_DHCP, &flow,
485                    (OFPFW_IN_PORT | OFPFW_DL_TYPE | OFPFW_DL_SRC
486                     | OFPFW_NW_PROTO | OFPFW_TP_SRC | OFPFW_TP_DST), 
487                    OFPP_NORMAL);
488
489         /* Allow the connection's interface to receive directed ARP traffic. */
490         memset(&flow, 0, sizeof flow);
491         flow.dl_type = htons(ETH_TYPE_ARP);
492         memcpy(flow.dl_dst, local_mac, ETH_ADDR_LEN);
493         flow.nw_proto = ARP_OP_REPLY;
494         setup_flow(in_band, IBR_TO_LOCAL_ARP, &flow,
495                    (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO), 
496                    OFPP_NORMAL);
497
498         /* Allow the connection's interface to be the source of ARP traffic. */
499         memset(&flow, 0, sizeof flow);
500         flow.dl_type = htons(ETH_TYPE_ARP);
501         memcpy(flow.dl_src, local_mac, ETH_ADDR_LEN);
502         flow.nw_proto = ARP_OP_REQUEST;
503         setup_flow(in_band, IBR_FROM_LOCAL_ARP, &flow,
504                    (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO),
505                    OFPP_NORMAL);
506     } else {
507         drop_flow(in_band, IBR_TO_LOCAL_ARP);
508         drop_flow(in_band, IBR_FROM_LOCAL_ARP);
509     }
510
511     if (remote_mac) {
512         /* Allow ARP replies to the remote side's MAC. */
513         memset(&flow, 0, sizeof flow);
514         flow.dl_type = htons(ETH_TYPE_ARP);
515         memcpy(flow.dl_dst, remote_mac, ETH_ADDR_LEN);
516         flow.nw_proto = ARP_OP_REPLY;
517         setup_flow(in_band, IBR_TO_REMOTE_ARP, &flow,
518                    (OFPFW_DL_TYPE | OFPFW_DL_DST | OFPFW_NW_PROTO), 
519                    OFPP_NORMAL);
520
521        /* Allow ARP requests from the remote side's MAC. */
522         memset(&flow, 0, sizeof flow);
523         flow.dl_type = htons(ETH_TYPE_ARP);
524         memcpy(flow.dl_src, remote_mac, ETH_ADDR_LEN);
525         flow.nw_proto = ARP_OP_REQUEST;
526         setup_flow(in_band, IBR_FROM_REMOTE_ARP, &flow,
527                    (OFPFW_DL_TYPE | OFPFW_DL_SRC | OFPFW_NW_PROTO), 
528                    OFPP_NORMAL);
529     } else {
530         drop_flow(in_band, IBR_TO_REMOTE_ARP);
531         drop_flow(in_band, IBR_FROM_REMOTE_ARP);
532     }
533
534     if (controller_ip) {
535         /* Allow ARP replies to the controller's IP. */
536         memset(&flow, 0, sizeof flow);
537         flow.dl_type = htons(ETH_TYPE_ARP);
538         flow.nw_proto = ARP_OP_REPLY;
539         flow.nw_dst = controller_ip;
540         setup_flow(in_band, IBR_TO_CTL_ARP, &flow,
541                    (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_DST_MASK),
542                    OFPP_NORMAL);
543
544        /* Allow ARP requests from the controller's IP. */
545         memset(&flow, 0, sizeof flow);
546         flow.dl_type = htons(ETH_TYPE_ARP);
547         flow.nw_proto = ARP_OP_REQUEST;
548         flow.nw_src = controller_ip;
549         setup_flow(in_band, IBR_FROM_CTL_ARP, &flow,
550                    (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK),
551                    OFPP_NORMAL);
552      
553         /* OpenFlow traffic to or from the controller.
554          *
555          * (A given field's value is completely ignored if it is wildcarded,
556          * which is why we can get away with using a single 'flow' in each
557          * case here.) */
558         memset(&flow, 0, sizeof flow);
559         flow.dl_type = htons(ETH_TYPE_IP);
560         flow.nw_proto = IP_TYPE_TCP;
561         flow.nw_src = controller_ip;
562         flow.nw_dst = controller_ip;
563         flow.tp_src = htons(OFP_TCP_PORT);
564         flow.tp_dst = htons(OFP_TCP_PORT);
565         setup_flow(in_band, IBR_TO_CTL_OFP, &flow,
566                    (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_DST_MASK 
567                     | OFPFW_TP_DST), OFPP_NORMAL);
568         setup_flow(in_band, IBR_FROM_CTL_OFP, &flow,
569                    (OFPFW_DL_TYPE | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK
570                     | OFPFW_TP_SRC), OFPP_NORMAL);
571     } else {
572         drop_flow(in_band, IBR_TO_CTL_ARP);
573         drop_flow(in_band, IBR_FROM_CTL_ARP);
574         drop_flow(in_band, IBR_TO_CTL_OFP);
575         drop_flow(in_band, IBR_FROM_CTL_OFP);
576     }
577 }
578
579 void
580 in_band_wait(struct in_band *in_band)
581 {
582     time_t now = time_now();
583     time_t wakeup 
584             = MIN(in_band->next_remote_refresh, in_band->next_local_refresh);
585     if (wakeup > now) {
586         poll_timer_wait((wakeup - now) * 1000);
587     } else {
588         poll_immediate_wake();
589     }
590 }
591
592 void
593 in_band_flushed(struct in_band *in_band)
594 {
595     int i;
596
597     for (i = 0; i < N_IB_RULES; i++) {
598         in_band->rules[i].installed = false;
599     }
600 }
601
602 int
603 in_band_create(struct ofproto *ofproto, struct dpif *dpif,
604                struct switch_status *ss, struct rconn *controller, 
605                struct in_band **in_bandp)
606 {
607     struct in_band *in_band;
608     char local_name[IF_NAMESIZE];
609     struct netdev *local_netdev;
610     int error;
611
612     error = dpif_port_get_name(dpif, ODPP_LOCAL,
613                                local_name, sizeof local_name);
614     if (error) {
615         VLOG_ERR("failed to initialize in-band control: cannot get name "
616                  "of datapath local port (%s)", strerror(error));
617         return error;
618     }
619
620     error = netdev_open(local_name, NETDEV_ETH_TYPE_NONE, &local_netdev);
621     if (error) {
622         VLOG_ERR("failed to initialize in-band control: cannot open "
623                  "datapath local port %s (%s)", local_name, strerror(error));
624         return error;
625     }
626
627     in_band = xcalloc(1, sizeof *in_band);
628     in_band->ofproto = ofproto;
629     in_band->controller = controller;
630     in_band->ss_cat = switch_status_register(ss, "in-band",
631                                              in_band_status_cb, in_band);
632     in_band->local_netdev = local_netdev;
633     in_band->next_local_refresh = TIME_MIN;
634     in_band->remote_netdev = NULL;
635     in_band->next_remote_refresh = TIME_MIN;
636
637     *in_bandp = in_band;
638
639     return 0;
640 }
641
642 void
643 in_band_destroy(struct in_band *in_band)
644 {
645     if (in_band) {
646         switch_status_unregister(in_band->ss_cat);
647         netdev_close(in_band->local_netdev);
648         netdev_close(in_band->remote_netdev);
649         /* We don't own the rconn. */
650     }
651 }
652