LCOV - code coverage report
Current view: top level - ofproto - connmgr.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 745 865 86.1 %
Date: 2016-09-14 01:02:56 Functions: 95 104 91.3 %
Branches: 346 516 67.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
       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 <errno.h>
      19                 :            : #include <stdlib.h>
      20                 :            : 
      21                 :            : #include "bundles.h"
      22                 :            : #include "connmgr.h"
      23                 :            : #include "coverage.h"
      24                 :            : #include "fail-open.h"
      25                 :            : #include "in-band.h"
      26                 :            : #include "odp-util.h"
      27                 :            : #include "ofproto-provider.h"
      28                 :            : #include "openvswitch/dynamic-string.h"
      29                 :            : #include "openvswitch/ofp-actions.h"
      30                 :            : #include "openvswitch/ofp-msgs.h"
      31                 :            : #include "openvswitch/ofp-util.h"
      32                 :            : #include "openvswitch/ofpbuf.h"
      33                 :            : #include "openvswitch/vconn.h"
      34                 :            : #include "openvswitch/vlog.h"
      35                 :            : #include "pinsched.h"
      36                 :            : #include "poll-loop.h"
      37                 :            : #include "rconn.h"
      38                 :            : #include "openvswitch/shash.h"
      39                 :            : #include "simap.h"
      40                 :            : #include "stream.h"
      41                 :            : #include "timeval.h"
      42                 :            : #include "util.h"
      43                 :            : 
      44                 :       1288 : VLOG_DEFINE_THIS_MODULE(connmgr);
      45                 :            : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
      46                 :            : 
      47                 :            : /* An OpenFlow connection.
      48                 :            :  *
      49                 :            :  *
      50                 :            :  * Thread-safety
      51                 :            :  * =============
      52                 :            :  *
      53                 :            :  * 'ofproto_mutex' must be held whenever an ofconn is created or destroyed or,
      54                 :            :  * more or less equivalently, whenever an ofconn is added to or removed from a
      55                 :            :  * connmgr.  'ofproto_mutex' doesn't protect the data inside the ofconn, except
      56                 :            :  * as specifically noted below. */
      57                 :            : struct ofconn {
      58                 :            : /* Configuration that persists from one connection to the next. */
      59                 :            : 
      60                 :            :     struct ovs_list node;       /* In struct connmgr's "all_conns" list. */
      61                 :            :     struct hmap_node hmap_node; /* In struct connmgr's "controllers" map. */
      62                 :            : 
      63                 :            :     struct connmgr *connmgr;    /* Connection's manager. */
      64                 :            :     struct rconn *rconn;        /* OpenFlow connection. */
      65                 :            :     enum ofconn_type type;      /* Type. */
      66                 :            :     enum ofproto_band band;     /* In-band or out-of-band? */
      67                 :            :     bool enable_async_msgs;     /* Initially enable async messages? */
      68                 :            : 
      69                 :            : /* State that should be cleared from one connection to the next. */
      70                 :            : 
      71                 :            :     /* OpenFlow state. */
      72                 :            :     enum ofp12_controller_role role;           /* Role. */
      73                 :            :     enum ofputil_protocol protocol; /* Current protocol variant. */
      74                 :            :     enum nx_packet_in_format packet_in_format; /* OFPT_PACKET_IN format. */
      75                 :            : 
      76                 :            :     /* OFPT_PACKET_IN related data. */
      77                 :            :     struct rconn_packet_counter *packet_in_counter; /* # queued on 'rconn'. */
      78                 :            : #define N_SCHEDULERS 2
      79                 :            :     struct pinsched *schedulers[N_SCHEDULERS];
      80                 :            :     int miss_send_len;             /* Bytes to send of buffered packets. */
      81                 :            :     uint16_t controller_id;     /* Connection controller ID. */
      82                 :            : 
      83                 :            :     /* Number of OpenFlow messages queued on 'rconn' as replies to OpenFlow
      84                 :            :      * requests, and the maximum number before we stop reading OpenFlow
      85                 :            :      * requests.  */
      86                 :            : #define OFCONN_REPLY_MAX 100
      87                 :            :     struct rconn_packet_counter *reply_counter;
      88                 :            : 
      89                 :            :     /* Asynchronous message configuration in each possible role.
      90                 :            :      *
      91                 :            :      * A 1-bit enables sending an asynchronous message for one possible reason
      92                 :            :      * that the message might be generated, a 0-bit disables it. */
      93                 :            :     struct ofputil_async_cfg *async_cfg;
      94                 :            : 
      95                 :            :     /* Flow table operation logging. */
      96                 :            :     int n_add, n_delete, n_modify; /* Number of unreported ops of each kind. */
      97                 :            :     long long int first_op, last_op; /* Range of times for unreported ops. */
      98                 :            :     long long int next_op_report;    /* Time to report ops, or LLONG_MAX. */
      99                 :            :     long long int op_backoff;        /* Earliest time to report ops again. */
     100                 :            : 
     101                 :            : /* Flow monitors (e.g. NXST_FLOW_MONITOR). */
     102                 :            : 
     103                 :            :     /* Configuration.  Contains "struct ofmonitor"s. */
     104                 :            :     struct hmap monitors OVS_GUARDED_BY(ofproto_mutex);
     105                 :            : 
     106                 :            :     /* Flow control.
     107                 :            :      *
     108                 :            :      * When too many flow monitor notifications back up in the transmit buffer,
     109                 :            :      * we pause the transmission of further notifications.  These members track
     110                 :            :      * the flow control state.
     111                 :            :      *
     112                 :            :      * When notifications are flowing, 'monitor_paused' is 0.  When
     113                 :            :      * notifications are paused, 'monitor_paused' is the value of
     114                 :            :      * 'monitor_seqno' at the point we paused.
     115                 :            :      *
     116                 :            :      * 'monitor_counter' counts the OpenFlow messages and bytes currently in
     117                 :            :      * flight.  This value growing too large triggers pausing. */
     118                 :            :     uint64_t monitor_paused OVS_GUARDED_BY(ofproto_mutex);
     119                 :            :     struct rconn_packet_counter *monitor_counter OVS_GUARDED_BY(ofproto_mutex);
     120                 :            : 
     121                 :            :     /* State of monitors for a single ongoing flow_mod.
     122                 :            :      *
     123                 :            :      * 'updates' is a list of "struct ofpbuf"s that contain
     124                 :            :      * NXST_FLOW_MONITOR_REPLY messages representing the changes made by the
     125                 :            :      * current flow_mod.
     126                 :            :      *
     127                 :            :      * When 'updates' is nonempty, 'sent_abbrev_update' is true if 'updates'
     128                 :            :      * contains an update event of type NXFME_ABBREV and false otherwise.. */
     129                 :            :     struct ovs_list updates OVS_GUARDED_BY(ofproto_mutex);
     130                 :            :     bool sent_abbrev_update OVS_GUARDED_BY(ofproto_mutex);
     131                 :            : 
     132                 :            :     /* Active bundles. Contains "struct ofp_bundle"s. */
     133                 :            :     struct hmap bundles;
     134                 :            : };
     135                 :            : 
     136                 :            : static struct ofconn *ofconn_create(struct connmgr *, struct rconn *,
     137                 :            :                                     enum ofconn_type, bool enable_async_msgs)
     138                 :            :     OVS_REQUIRES(ofproto_mutex);
     139                 :            : static void ofconn_destroy(struct ofconn *) OVS_REQUIRES(ofproto_mutex);
     140                 :            : static void ofconn_flush(struct ofconn *) OVS_REQUIRES(ofproto_mutex);
     141                 :            : 
     142                 :            : static void ofconn_reconfigure(struct ofconn *,
     143                 :            :                                const struct ofproto_controller *);
     144                 :            : 
     145                 :            : static void ofconn_run(struct ofconn *,
     146                 :            :                        void (*handle_openflow)(struct ofconn *,
     147                 :            :                                                const struct ofpbuf *ofp_msg));
     148                 :            : static void ofconn_wait(struct ofconn *);
     149                 :            : 
     150                 :            : static void ofconn_log_flow_mods(struct ofconn *);
     151                 :            : 
     152                 :            : static const char *ofconn_get_target(const struct ofconn *);
     153                 :            : static char *ofconn_make_name(const struct connmgr *, const char *target);
     154                 :            : 
     155                 :            : static void ofconn_set_rate_limit(struct ofconn *, int rate, int burst);
     156                 :            : 
     157                 :            : static void ofconn_send(const struct ofconn *, struct ofpbuf *,
     158                 :            :                         struct rconn_packet_counter *);
     159                 :            : 
     160                 :            : static void do_send_packet_ins(struct ofconn *, struct ovs_list *txq);
     161                 :            : 
     162                 :            : /* A listener for incoming OpenFlow "service" connections. */
     163                 :            : struct ofservice {
     164                 :            :     struct hmap_node node;      /* In struct connmgr's "services" hmap. */
     165                 :            :     struct pvconn *pvconn;      /* OpenFlow connection listener. */
     166                 :            : 
     167                 :            :     /* These are not used by ofservice directly.  They are settings for
     168                 :            :      * accepted "struct ofconn"s from the pvconn. */
     169                 :            :     int probe_interval;         /* Max idle time before probing, in seconds. */
     170                 :            :     int rate_limit;             /* Max packet-in rate in packets per second. */
     171                 :            :     int burst_limit;            /* Limit on accumulating packet credits. */
     172                 :            :     bool enable_async_msgs;     /* Initially enable async messages? */
     173                 :            :     uint8_t dscp;               /* DSCP Value for controller connection */
     174                 :            :     uint32_t allowed_versions;  /* OpenFlow protocol versions that may
     175                 :            :                                  * be negotiated for a session. */
     176                 :            : };
     177                 :            : 
     178                 :            : static void ofservice_reconfigure(struct ofservice *,
     179                 :            :                                   const struct ofproto_controller *);
     180                 :            : static int ofservice_create(struct connmgr *mgr, const char *target,
     181                 :            :                             uint32_t allowed_versions, uint8_t dscp);
     182                 :            : static void ofservice_destroy(struct connmgr *, struct ofservice *);
     183                 :            : static struct ofservice *ofservice_lookup(struct connmgr *,
     184                 :            :                                           const char *target);
     185                 :            : 
     186                 :            : /* Connection manager for an OpenFlow switch. */
     187                 :            : struct connmgr {
     188                 :            :     struct ofproto *ofproto;
     189                 :            :     char *name;
     190                 :            :     char *local_port_name;
     191                 :            : 
     192                 :            :     /* OpenFlow connections. */
     193                 :            :     struct hmap controllers;     /* All OFCONN_PRIMARY controllers. */
     194                 :            :     struct ovs_list all_conns;   /* All controllers. */
     195                 :            :     uint64_t master_election_id; /* monotonically increasing sequence number
     196                 :            :                                   * for master election */
     197                 :            :     bool master_election_id_defined;
     198                 :            : 
     199                 :            :     /* OpenFlow listeners. */
     200                 :            :     struct hmap services;       /* Contains "struct ofservice"s. */
     201                 :            :     struct pvconn **snoops;
     202                 :            :     size_t n_snoops;
     203                 :            : 
     204                 :            :     /* Fail open. */
     205                 :            :     struct fail_open *fail_open;
     206                 :            :     enum ofproto_fail_mode fail_mode;
     207                 :            : 
     208                 :            :     /* In-band control. */
     209                 :            :     struct in_band *in_band;
     210                 :            :     struct sockaddr_in *extra_in_band_remotes;
     211                 :            :     size_t n_extra_remotes;
     212                 :            :     int in_band_queue;
     213                 :            : };
     214                 :            : 
     215                 :            : static void update_in_band_remotes(struct connmgr *);
     216                 :            : static void add_snooper(struct connmgr *, struct vconn *);
     217                 :            : static void ofmonitor_run(struct connmgr *);
     218                 :            : static void ofmonitor_wait(struct connmgr *);
     219                 :            : 
     220                 :            : /* Creates and returns a new connection manager owned by 'ofproto'.  'name' is
     221                 :            :  * a name for the ofproto suitable for using in log messages.
     222                 :            :  * 'local_port_name' is the name of the local port (OFPP_LOCAL) within
     223                 :            :  * 'ofproto'. */
     224                 :            : struct connmgr *
     225                 :        749 : connmgr_create(struct ofproto *ofproto,
     226                 :            :                const char *name, const char *local_port_name)
     227                 :            : {
     228                 :            :     struct connmgr *mgr;
     229                 :            : 
     230                 :        749 :     mgr = xmalloc(sizeof *mgr);
     231                 :        749 :     mgr->ofproto = ofproto;
     232                 :        749 :     mgr->name = xstrdup(name);
     233                 :        749 :     mgr->local_port_name = xstrdup(local_port_name);
     234                 :            : 
     235                 :        749 :     hmap_init(&mgr->controllers);
     236                 :        749 :     ovs_list_init(&mgr->all_conns);
     237                 :        749 :     mgr->master_election_id = 0;
     238                 :        749 :     mgr->master_election_id_defined = false;
     239                 :            : 
     240                 :        749 :     hmap_init(&mgr->services);
     241                 :        749 :     mgr->snoops = NULL;
     242                 :        749 :     mgr->n_snoops = 0;
     243                 :            : 
     244                 :        749 :     mgr->fail_open = NULL;
     245                 :        749 :     mgr->fail_mode = OFPROTO_FAIL_SECURE;
     246                 :            : 
     247                 :        749 :     mgr->in_band = NULL;
     248                 :        749 :     mgr->extra_in_band_remotes = NULL;
     249                 :        749 :     mgr->n_extra_remotes = 0;
     250                 :        749 :     mgr->in_band_queue = -1;
     251                 :            : 
     252                 :        749 :     return mgr;
     253                 :            : }
     254                 :            : 
     255                 :            : /* Frees 'mgr' and all of its resources. */
     256                 :            : void
     257                 :        749 : connmgr_destroy(struct connmgr *mgr)
     258                 :            : {
     259                 :            :     struct ofservice *ofservice, *next_ofservice;
     260                 :            :     struct ofconn *ofconn, *next_ofconn;
     261                 :            :     size_t i;
     262                 :            : 
     263         [ -  + ]:        749 :     if (!mgr) {
     264                 :          0 :         return;
     265                 :            :     }
     266                 :            : 
     267                 :        749 :     ovs_mutex_lock(&ofproto_mutex);
     268 [ +  + ][ +  + ]:        779 :     LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
     269                 :         30 :         ofconn_destroy(ofconn);
     270                 :            :     }
     271                 :        749 :     ovs_mutex_unlock(&ofproto_mutex);
     272                 :            : 
     273                 :        749 :     hmap_destroy(&mgr->controllers);
     274                 :            : 
     275 [ +  + ][ -  + ]:       1498 :     HMAP_FOR_EACH_SAFE (ofservice, next_ofservice, node, &mgr->services) {
                 [ +  + ]
     276                 :        749 :         ofservice_destroy(mgr, ofservice);
     277                 :            :     }
     278                 :        749 :     hmap_destroy(&mgr->services);
     279                 :            : 
     280         [ +  + ]:       1498 :     for (i = 0; i < mgr->n_snoops; i++) {
     281                 :        749 :         pvconn_close(mgr->snoops[i]);
     282                 :            :     }
     283                 :        749 :     free(mgr->snoops);
     284                 :            : 
     285                 :        749 :     fail_open_destroy(mgr->fail_open);
     286                 :        749 :     mgr->fail_open = NULL;
     287                 :            : 
     288                 :        749 :     in_band_destroy(mgr->in_band);
     289                 :        749 :     mgr->in_band = NULL;
     290                 :        749 :     free(mgr->extra_in_band_remotes);
     291                 :        749 :     free(mgr->name);
     292                 :        749 :     free(mgr->local_port_name);
     293                 :            : 
     294                 :        749 :     free(mgr);
     295                 :            : }
     296                 :            : 
     297                 :            : /* Does all of the periodic maintenance required by 'mgr'.  Calls
     298                 :            :  * 'handle_openflow' for each message received on an OpenFlow connection,
     299                 :            :  * passing along the OpenFlow connection itself and the message that was sent.
     300                 :            :  * 'handle_openflow' must not modify or free the message. */
     301                 :            : void
     302                 :     157605 : connmgr_run(struct connmgr *mgr,
     303                 :            :             void (*handle_openflow)(struct ofconn *,
     304                 :            :                                     const struct ofpbuf *ofp_msg))
     305                 :            :     OVS_EXCLUDED(ofproto_mutex)
     306                 :            : {
     307                 :            :     struct ofconn *ofconn, *next_ofconn;
     308                 :            :     struct ofservice *ofservice;
     309                 :            :     size_t i;
     310                 :            : 
     311         [ +  + ]:     157605 :     if (mgr->in_band) {
     312         [ -  + ]:         48 :         if (!in_band_run(mgr->in_band)) {
     313                 :          0 :             in_band_destroy(mgr->in_band);
     314                 :          0 :             mgr->in_band = NULL;
     315                 :            :         }
     316                 :            :     }
     317                 :            : 
     318 [ +  + ][ +  + ]:     261611 :     LIST_FOR_EACH_SAFE (ofconn, next_ofconn, node, &mgr->all_conns) {
     319                 :     104006 :         ofconn_run(ofconn, handle_openflow);
     320                 :            :     }
     321                 :     157605 :     ofmonitor_run(mgr);
     322                 :            : 
     323                 :            :     /* Fail-open maintenance.  Do this after processing the ofconns since
     324                 :            :      * fail-open checks the status of the controller rconn. */
     325         [ -  + ]:     157605 :     if (mgr->fail_open) {
     326                 :          0 :         fail_open_run(mgr->fail_open);
     327                 :            :     }
     328                 :            : 
     329 [ +  + ][ -  + ]:     315213 :     HMAP_FOR_EACH (ofservice, node, &mgr->services) {
     330                 :            :         struct vconn *vconn;
     331                 :            :         int retval;
     332                 :            : 
     333                 :     157608 :         retval = pvconn_accept(ofservice->pvconn, &vconn);
     334         [ +  + ]:     157608 :         if (!retval) {
     335                 :            :             struct rconn *rconn;
     336                 :            :             char *name;
     337                 :            : 
     338                 :            :             /* Passing default value for creation of the rconn */
     339                 :       3419 :             rconn = rconn_create(ofservice->probe_interval, 0, ofservice->dscp,
     340                 :            :                                  vconn_get_allowed_versions(vconn));
     341                 :       3419 :             name = ofconn_make_name(mgr, vconn_get_name(vconn));
     342                 :       3419 :             rconn_connect_unreliably(rconn, vconn, name);
     343                 :       3419 :             free(name);
     344                 :            : 
     345                 :       3419 :             ovs_mutex_lock(&ofproto_mutex);
     346                 :       3419 :             ofconn = ofconn_create(mgr, rconn, OFCONN_SERVICE,
     347                 :       3419 :                                    ofservice->enable_async_msgs);
     348                 :       3419 :             ovs_mutex_unlock(&ofproto_mutex);
     349                 :            : 
     350                 :       3419 :             ofconn_set_rate_limit(ofconn, ofservice->rate_limit,
     351                 :            :                                   ofservice->burst_limit);
     352         [ -  + ]:     154189 :         } else if (retval != EAGAIN) {
     353         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "accept failed (%s)", ovs_strerror(retval));
     354                 :            :         }
     355                 :            :     }
     356                 :            : 
     357         [ +  + ]:     315210 :     for (i = 0; i < mgr->n_snoops; i++) {
     358                 :            :         struct vconn *vconn;
     359                 :            :         int retval;
     360                 :            : 
     361                 :     157605 :         retval = pvconn_accept(mgr->snoops[i], &vconn);
     362         [ -  + ]:     157605 :         if (!retval) {
     363                 :          0 :             add_snooper(mgr, vconn);
     364         [ -  + ]:     157605 :         } else if (retval != EAGAIN) {
     365         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "accept failed (%s)", ovs_strerror(retval));
     366                 :            :         }
     367                 :            :     }
     368                 :     157605 : }
     369                 :            : 
     370                 :            : /* Causes the poll loop to wake up when connmgr_run() needs to run. */
     371                 :            : void
     372                 :     153645 : connmgr_wait(struct connmgr *mgr)
     373                 :            : {
     374                 :            :     struct ofservice *ofservice;
     375                 :            :     struct ofconn *ofconn;
     376                 :            :     size_t i;
     377                 :            : 
     378         [ +  + ]:     256921 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
     379                 :     103276 :         ofconn_wait(ofconn);
     380                 :            :     }
     381                 :     153645 :     ofmonitor_wait(mgr);
     382         [ +  + ]:     153645 :     if (mgr->in_band) {
     383                 :         48 :         in_band_wait(mgr->in_band);
     384                 :            :     }
     385         [ -  + ]:     153645 :     if (mgr->fail_open) {
     386                 :          0 :         fail_open_wait(mgr->fail_open);
     387                 :            :     }
     388 [ +  + ][ -  + ]:     307292 :     HMAP_FOR_EACH (ofservice, node, &mgr->services) {
     389                 :     153647 :         pvconn_wait(ofservice->pvconn);
     390                 :            :     }
     391         [ +  + ]:     307290 :     for (i = 0; i < mgr->n_snoops; i++) {
     392                 :     153645 :         pvconn_wait(mgr->snoops[i]);
     393                 :            :     }
     394                 :     153645 : }
     395                 :            : 
     396                 :            : /* Adds some memory usage statistics for 'mgr' into 'usage', for use with
     397                 :            :  * memory_report(). */
     398                 :            : void
     399                 :        109 : connmgr_get_memory_usage(const struct connmgr *mgr, struct simap *usage)
     400                 :            : {
     401                 :            :     const struct ofconn *ofconn;
     402                 :        109 :     unsigned int packets = 0;
     403                 :        109 :     unsigned int ofconns = 0;
     404                 :            : 
     405         [ +  + ]:        135 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
     406                 :            :         int i;
     407                 :            : 
     408                 :         26 :         ofconns++;
     409                 :            : 
     410                 :         26 :         packets += rconn_count_txqlen(ofconn->rconn);
     411         [ +  + ]:         78 :         for (i = 0; i < N_SCHEDULERS; i++) {
     412                 :            :             struct pinsched_stats stats;
     413                 :            : 
     414                 :         52 :             pinsched_get_stats(ofconn->schedulers[i], &stats);
     415                 :         52 :             packets += stats.n_queued;
     416                 :            :         }
     417                 :            :     }
     418                 :        109 :     simap_increase(usage, "ofconns", ofconns);
     419                 :        109 :     simap_increase(usage, "packets", packets);
     420                 :        109 : }
     421                 :            : 
     422                 :            : /* Returns the ofproto that owns 'ofconn''s connmgr. */
     423                 :            : struct ofproto *
     424                 :      36734 : ofconn_get_ofproto(const struct ofconn *ofconn)
     425                 :            : {
     426                 :      36734 :     return ofconn->connmgr->ofproto;
     427                 :            : }
     428                 :            : 
     429                 :            : /* OpenFlow configuration. */
     430                 :            : 
     431                 :            : static void add_controller(struct connmgr *, const char *target, uint8_t dscp,
     432                 :            :                            uint32_t allowed_versions)
     433                 :            :     OVS_REQUIRES(ofproto_mutex);
     434                 :            : static struct ofconn *find_controller_by_target(struct connmgr *,
     435                 :            :                                                 const char *target);
     436                 :            : static void update_fail_open(struct connmgr *) OVS_EXCLUDED(ofproto_mutex);
     437                 :            : static int set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp,
     438                 :            :                        const struct sset *);
     439                 :            : 
     440                 :            : /* Returns true if 'mgr' has any configured primary controllers.
     441                 :            :  *
     442                 :            :  * Service controllers do not count, but configured primary controllers do
     443                 :            :  * count whether or not they are currently connected. */
     444                 :            : bool
     445                 :      14536 : connmgr_has_controllers(const struct connmgr *mgr)
     446                 :            : {
     447                 :      14536 :     return !hmap_is_empty(&mgr->controllers);
     448                 :            : }
     449                 :            : 
     450                 :            : /* Initializes 'info' and populates it with information about each configured
     451                 :            :  * primary controller.  The keys in 'info' are the controllers' targets; the
     452                 :            :  * data values are corresponding "struct ofproto_controller_info".
     453                 :            :  *
     454                 :            :  * The caller owns 'info' and everything in it and should free it when it is no
     455                 :            :  * longer needed. */
     456                 :            : void
     457                 :        901 : connmgr_get_controller_info(struct connmgr *mgr, struct shash *info)
     458                 :            : {
     459                 :            :     const struct ofconn *ofconn;
     460                 :            : 
     461 [ +  + ][ -  + ]:        903 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
     462                 :          2 :         const struct rconn *rconn = ofconn->rconn;
     463                 :          2 :         const char *target = rconn_get_target(rconn);
     464                 :            : 
     465         [ +  - ]:          2 :         if (!shash_find(info, target)) {
     466                 :          2 :             struct ofproto_controller_info *cinfo = xmalloc(sizeof *cinfo);
     467                 :          2 :             time_t now = time_now();
     468                 :          2 :             time_t last_connection = rconn_get_last_connection(rconn);
     469                 :          2 :             time_t last_disconnect = rconn_get_last_disconnect(rconn);
     470                 :          2 :             int last_error = rconn_get_last_error(rconn);
     471                 :            :             int i;
     472                 :            : 
     473                 :          2 :             shash_add(info, target, cinfo);
     474                 :            : 
     475                 :          2 :             cinfo->is_connected = rconn_is_connected(rconn);
     476                 :          2 :             cinfo->role = ofconn->role;
     477                 :            : 
     478                 :          2 :             smap_init(&cinfo->pairs);
     479         [ +  - ]:          2 :             if (last_error) {
     480                 :          2 :                 smap_add(&cinfo->pairs, "last_error",
     481                 :            :                          ovs_retval_to_string(last_error));
     482                 :            :             }
     483                 :            : 
     484                 :          2 :             smap_add(&cinfo->pairs, "state", rconn_get_state(rconn));
     485                 :            : 
     486         [ -  + ]:          2 :             if (last_connection != TIME_MIN) {
     487                 :          0 :                 smap_add_format(&cinfo->pairs, "sec_since_connect",
     488                 :          0 :                                 "%ld", (long int) (now - last_connection));
     489                 :            :             }
     490                 :            : 
     491         [ +  - ]:          2 :             if (last_disconnect != TIME_MIN) {
     492                 :          2 :                 smap_add_format(&cinfo->pairs, "sec_since_disconnect",
     493                 :          2 :                                 "%ld", (long int) (now - last_disconnect));
     494                 :            :             }
     495                 :            : 
     496         [ +  + ]:          6 :             for (i = 0; i < N_SCHEDULERS; i++) {
     497         [ -  + ]:          4 :                 if (ofconn->schedulers[i]) {
     498         [ #  # ]:          0 :                     const char *name = i ? "miss" : "action";
     499                 :            :                     struct pinsched_stats stats;
     500                 :            : 
     501                 :          0 :                     pinsched_get_stats(ofconn->schedulers[i], &stats);
     502                 :          0 :                     smap_add_nocopy(&cinfo->pairs,
     503                 :            :                                     xasprintf("packet-in-%s-backlog", name),
     504                 :            :                                     xasprintf("%u", stats.n_queued));
     505                 :          0 :                     smap_add_nocopy(&cinfo->pairs,
     506                 :            :                                     xasprintf("packet-in-%s-bypassed", name),
     507                 :            :                                     xasprintf("%llu", stats.n_normal));
     508                 :          0 :                     smap_add_nocopy(&cinfo->pairs,
     509                 :            :                                     xasprintf("packet-in-%s-queued", name),
     510                 :            :                                     xasprintf("%llu", stats.n_limited));
     511                 :          0 :                     smap_add_nocopy(&cinfo->pairs,
     512                 :            :                                     xasprintf("packet-in-%s-dropped", name),
     513                 :            :                                     xasprintf("%llu", stats.n_queue_dropped));
     514                 :            :                 }
     515                 :            :             }
     516                 :            :         }
     517                 :            :     }
     518                 :        901 : }
     519                 :            : 
     520                 :            : void
     521                 :       1178 : connmgr_free_controller_info(struct shash *info)
     522                 :            : {
     523                 :            :     struct shash_node *node;
     524                 :            : 
     525 [ +  + ][ -  + ]:       1180 :     SHASH_FOR_EACH (node, info) {
     526                 :          2 :         struct ofproto_controller_info *cinfo = node->data;
     527                 :          2 :         smap_destroy(&cinfo->pairs);
     528                 :          2 :         free(cinfo);
     529                 :            :     }
     530                 :       1178 :     shash_destroy(info);
     531                 :       1178 : }
     532                 :            : 
     533                 :            : /* Changes 'mgr''s set of controllers to the 'n_controllers' controllers in
     534                 :            :  * 'controllers'. */
     535                 :            : void
     536                 :       4700 : connmgr_set_controllers(struct connmgr *mgr,
     537                 :            :                         const struct ofproto_controller *controllers,
     538                 :            :                         size_t n_controllers, uint32_t allowed_versions)
     539                 :            :     OVS_EXCLUDED(ofproto_mutex)
     540                 :            : {
     541                 :       4700 :     bool had_controllers = connmgr_has_controllers(mgr);
     542                 :            :     struct shash new_controllers;
     543                 :            :     struct ofconn *ofconn, *next_ofconn;
     544                 :            :     struct ofservice *ofservice, *next_ofservice;
     545                 :            :     size_t i;
     546                 :            : 
     547                 :            :     /* Required to add and remove ofconns.  This could probably be narrowed to
     548                 :            :      * cover a smaller amount of code, if that yielded some benefit. */
     549                 :       4700 :     ovs_mutex_lock(&ofproto_mutex);
     550                 :            : 
     551                 :            :     /* Create newly configured controllers and services.
     552                 :            :      * Create a name to ofproto_controller mapping in 'new_controllers'. */
     553                 :       4700 :     shash_init(&new_controllers);
     554         [ +  + ]:       9402 :     for (i = 0; i < n_controllers; i++) {
     555                 :       4702 :         const struct ofproto_controller *c = &controllers[i];
     556                 :            : 
     557         [ +  + ]:       4702 :         if (!vconn_verify_name(c->target)) {
     558                 :          1 :             bool add = false;
     559                 :          1 :             ofconn = find_controller_by_target(mgr, c->target);
     560         [ +  - ]:          1 :             if (!ofconn) {
     561         [ +  - ]:          1 :                 VLOG_INFO("%s: added primary controller \"%s\"",
     562                 :            :                           mgr->name, c->target);
     563                 :          1 :                 add = true;
     564         [ #  # ]:          0 :             } else if (rconn_get_allowed_versions(ofconn->rconn) !=
     565                 :            :                        allowed_versions) {
     566         [ #  # ]:          0 :                 VLOG_INFO("%s: re-added primary controller \"%s\"",
     567                 :            :                           mgr->name, c->target);
     568                 :          0 :                 add = true;
     569                 :          0 :                 ofconn_destroy(ofconn);
     570                 :            :             }
     571         [ +  - ]:          1 :             if (add) {
     572                 :          1 :                 add_controller(mgr, c->target, c->dscp, allowed_versions);
     573                 :            :             }
     574         [ +  - ]:       4701 :         } else if (!pvconn_verify_name(c->target)) {
     575                 :       4701 :             bool add = false;
     576                 :       4701 :             ofservice = ofservice_lookup(mgr, c->target);
     577         [ +  + ]:       4701 :             if (!ofservice) {
     578         [ +  - ]:        750 :                 VLOG_INFO("%s: added service controller \"%s\"",
     579                 :            :                           mgr->name, c->target);
     580                 :        750 :                 add = true;
     581         [ -  + ]:       3951 :             } else if (ofservice->allowed_versions != allowed_versions) {
     582         [ #  # ]:          0 :                 VLOG_INFO("%s: re-added service controller \"%s\"",
     583                 :            :                           mgr->name, c->target);
     584                 :          0 :                 ofservice_destroy(mgr, ofservice);
     585                 :          0 :                 add = true;
     586                 :            :             }
     587         [ +  + ]:       4701 :             if (add) {
     588                 :       4701 :                 ofservice_create(mgr, c->target, allowed_versions, c->dscp);
     589                 :            :             }
     590                 :            :         } else {
     591         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "%s: unsupported controller \"%s\"",
     592                 :            :                          mgr->name, c->target);
     593                 :          0 :             continue;
     594                 :            :         }
     595                 :            : 
     596                 :       4702 :         shash_add_once(&new_controllers, c->target, &controllers[i]);
     597                 :            :     }
     598                 :            : 
     599                 :            :     /* Delete controllers that are no longer configured.
     600                 :            :      * Update configuration of all now-existing controllers. */
     601 [ +  + ][ -  + ]:       4701 :     HMAP_FOR_EACH_SAFE (ofconn, next_ofconn, hmap_node, &mgr->controllers) {
                 [ +  + ]
     602                 :          1 :         const char *target = ofconn_get_target(ofconn);
     603                 :            :         struct ofproto_controller *c;
     604                 :            : 
     605                 :          1 :         c = shash_find_data(&new_controllers, target);
     606         [ -  + ]:          1 :         if (!c) {
     607         [ #  # ]:          0 :             VLOG_INFO("%s: removed primary controller \"%s\"",
     608                 :            :                       mgr->name, target);
     609                 :          0 :             ofconn_destroy(ofconn);
     610                 :            :         } else {
     611                 :          1 :             ofconn_reconfigure(ofconn, c);
     612                 :            :         }
     613                 :            :     }
     614                 :            : 
     615                 :            :     /* Delete services that are no longer configured.
     616                 :            :      * Update configuration of all now-existing services. */
     617 [ +  + ][ -  + ]:       9402 :     HMAP_FOR_EACH_SAFE (ofservice, next_ofservice, node, &mgr->services) {
                 [ +  + ]
     618                 :       4702 :         const char *target = pvconn_get_name(ofservice->pvconn);
     619                 :            :         struct ofproto_controller *c;
     620                 :            : 
     621                 :       4702 :         c = shash_find_data(&new_controllers, target);
     622         [ +  + ]:       4702 :         if (!c) {
     623         [ +  - ]:          1 :             VLOG_INFO("%s: removed service controller \"%s\"",
     624                 :            :                       mgr->name, target);
     625                 :          1 :             ofservice_destroy(mgr, ofservice);
     626                 :            :         } else {
     627                 :       4701 :             ofservice_reconfigure(ofservice, c);
     628                 :            :         }
     629                 :            :     }
     630                 :            : 
     631                 :       4700 :     shash_destroy(&new_controllers);
     632                 :            : 
     633                 :       4700 :     ovs_mutex_unlock(&ofproto_mutex);
     634                 :            : 
     635                 :       4700 :     update_in_band_remotes(mgr);
     636                 :       4700 :     update_fail_open(mgr);
     637         [ +  + ]:       4700 :     if (had_controllers != connmgr_has_controllers(mgr)) {
     638                 :          1 :         ofproto_flush_flows(mgr->ofproto);
     639                 :            :     }
     640                 :       4700 : }
     641                 :            : 
     642                 :            : /* Drops the connections between 'mgr' and all of its primary and secondary
     643                 :            :  * controllers, forcing them to reconnect. */
     644                 :            : void
     645                 :        749 : connmgr_reconnect(const struct connmgr *mgr)
     646                 :            : {
     647                 :            :     struct ofconn *ofconn;
     648                 :            : 
     649         [ -  + ]:        749 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
     650                 :          0 :         rconn_reconnect(ofconn->rconn);
     651                 :            :     }
     652                 :        749 : }
     653                 :            : 
     654                 :            : /* Sets the "snoops" for 'mgr' to the pvconn targets listed in 'snoops'.
     655                 :            :  *
     656                 :            :  * A "snoop" is a pvconn to which every OpenFlow message to or from the most
     657                 :            :  * important controller on 'mgr' is mirrored. */
     658                 :            : int
     659                 :        749 : connmgr_set_snoops(struct connmgr *mgr, const struct sset *snoops)
     660                 :            : {
     661                 :        749 :     return set_pvconns(&mgr->snoops, &mgr->n_snoops, snoops);
     662                 :            : }
     663                 :            : 
     664                 :            : /* Adds each of the snoops currently configured on 'mgr' to 'snoops'. */
     665                 :            : void
     666                 :          0 : connmgr_get_snoops(const struct connmgr *mgr, struct sset *snoops)
     667                 :            : {
     668                 :            :     size_t i;
     669                 :            : 
     670         [ #  # ]:          0 :     for (i = 0; i < mgr->n_snoops; i++) {
     671                 :          0 :         sset_add(snoops, pvconn_get_name(mgr->snoops[i]));
     672                 :            :     }
     673                 :          0 : }
     674                 :            : 
     675                 :            : /* Returns true if 'mgr' has at least one snoop, false if it has none. */
     676                 :            : bool
     677                 :       4700 : connmgr_has_snoops(const struct connmgr *mgr)
     678                 :            : {
     679                 :       4700 :     return mgr->n_snoops > 0;
     680                 :            : }
     681                 :            : 
     682                 :            : /* Creates a new controller for 'target' in 'mgr'.  update_controller() needs
     683                 :            :  * to be called later to finish the new ofconn's configuration. */
     684                 :            : static void
     685                 :          1 : add_controller(struct connmgr *mgr, const char *target, uint8_t dscp,
     686                 :            :                uint32_t allowed_versions)
     687                 :            :     OVS_REQUIRES(ofproto_mutex)
     688                 :            : {
     689                 :          1 :     char *name = ofconn_make_name(mgr, target);
     690                 :            :     struct ofconn *ofconn;
     691                 :            : 
     692                 :          1 :     ofconn = ofconn_create(mgr, rconn_create(5, 8, dscp, allowed_versions),
     693                 :            :                            OFCONN_PRIMARY, true);
     694                 :          1 :     rconn_connect(ofconn->rconn, target, name);
     695                 :          1 :     hmap_insert(&mgr->controllers, &ofconn->hmap_node, hash_string(target, 0));
     696                 :            : 
     697                 :          1 :     free(name);
     698                 :          1 : }
     699                 :            : 
     700                 :            : static struct ofconn *
     701                 :          1 : find_controller_by_target(struct connmgr *mgr, const char *target)
     702                 :            : {
     703                 :            :     struct ofconn *ofconn;
     704                 :            : 
     705 [ -  + ][ -  + ]:          1 :     HMAP_FOR_EACH_WITH_HASH (ofconn, hmap_node,
     706                 :            :                              hash_string(target, 0), &mgr->controllers) {
     707         [ #  # ]:          0 :         if (!strcmp(ofconn_get_target(ofconn), target)) {
     708                 :          0 :             return ofconn;
     709                 :            :         }
     710                 :            :     }
     711                 :          1 :     return NULL;
     712                 :            : }
     713                 :            : 
     714                 :            : static void
     715                 :       4700 : update_in_band_remotes(struct connmgr *mgr)
     716                 :            : {
     717                 :            :     struct sockaddr_in *addrs;
     718                 :            :     size_t max_addrs, n_addrs;
     719                 :            :     struct ofconn *ofconn;
     720                 :            :     size_t i;
     721                 :            : 
     722                 :            :     /* Allocate enough memory for as many remotes as we could possibly have. */
     723                 :       4700 :     max_addrs = mgr->n_extra_remotes + hmap_count(&mgr->controllers);
     724                 :       4700 :     addrs = xmalloc(max_addrs * sizeof *addrs);
     725                 :       4700 :     n_addrs = 0;
     726                 :            : 
     727                 :            :     /* Add all the remotes. */
     728 [ +  + ][ -  + ]:       4701 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
     729                 :          1 :         const char *target = rconn_get_target(ofconn->rconn);
     730                 :            :         union {
     731                 :            :             struct sockaddr_storage ss;
     732                 :            :             struct sockaddr_in in;
     733                 :            :         } sa;
     734                 :            : 
     735         [ +  - ]:          1 :         if (ofconn->band == OFPROTO_IN_BAND
     736         [ +  - ]:          1 :             && stream_parse_target_with_default_port(target, OFP_PORT, &sa.ss)
     737         [ +  - ]:          1 :             && sa.ss.ss_family == AF_INET) {
     738                 :          1 :             addrs[n_addrs++] = sa.in;
     739                 :            :         }
     740                 :            :     }
     741         [ -  + ]:       4700 :     for (i = 0; i < mgr->n_extra_remotes; i++) {
     742                 :          0 :         addrs[n_addrs++] = mgr->extra_in_band_remotes[i];
     743                 :            :     }
     744                 :            : 
     745                 :            :     /* Create or update or destroy in-band. */
     746         [ +  + ]:       4700 :     if (n_addrs) {
     747         [ +  - ]:          1 :         if (!mgr->in_band) {
     748                 :          1 :             in_band_create(mgr->ofproto, mgr->local_port_name, &mgr->in_band);
     749                 :            :         }
     750                 :          1 :         in_band_set_queue(mgr->in_band, mgr->in_band_queue);
     751                 :            :     } else {
     752                 :            :         /* in_band_run() needs a chance to delete any existing in-band flows.
     753                 :            :          * We will destroy mgr->in_band after it's done with that. */
     754                 :            :     }
     755         [ +  + ]:       4700 :     if (mgr->in_band) {
     756                 :          1 :         in_band_set_remotes(mgr->in_band, addrs, n_addrs);
     757                 :            :     }
     758                 :            : 
     759                 :            :     /* Clean up. */
     760                 :       4700 :     free(addrs);
     761                 :       4700 : }
     762                 :            : 
     763                 :            : static void
     764                 :       4845 : update_fail_open(struct connmgr *mgr)
     765                 :            :     OVS_EXCLUDED(ofproto_mutex)
     766                 :            : {
     767         [ +  + ]:       4845 :     if (connmgr_has_controllers(mgr)
     768         [ -  + ]:          1 :         && mgr->fail_mode == OFPROTO_FAIL_STANDALONE) {
     769         [ #  # ]:          0 :         if (!mgr->fail_open) {
     770                 :          0 :             mgr->fail_open = fail_open_create(mgr->ofproto, mgr);
     771                 :            :         }
     772                 :            :     } else {
     773                 :       4845 :         fail_open_destroy(mgr->fail_open);
     774                 :       4845 :         mgr->fail_open = NULL;
     775                 :            :     }
     776                 :       4845 : }
     777                 :            : 
     778                 :            : static int
     779                 :        749 : set_pvconns(struct pvconn ***pvconnsp, size_t *n_pvconnsp,
     780                 :            :             const struct sset *sset)
     781                 :            : {
     782                 :        749 :     struct pvconn **pvconns = *pvconnsp;
     783                 :        749 :     size_t n_pvconns = *n_pvconnsp;
     784                 :            :     const char *name;
     785                 :        749 :     int retval = 0;
     786                 :            :     size_t i;
     787                 :            : 
     788         [ -  + ]:        749 :     for (i = 0; i < n_pvconns; i++) {
     789                 :          0 :         pvconn_close(pvconns[i]);
     790                 :            :     }
     791                 :        749 :     free(pvconns);
     792                 :            : 
     793                 :        749 :     pvconns = xmalloc(sset_count(sset) * sizeof *pvconns);
     794                 :        749 :     n_pvconns = 0;
     795 [ +  - ][ -  + ]:       1498 :     SSET_FOR_EACH (name, sset) {
                 [ +  + ]
     796                 :            :         struct pvconn *pvconn;
     797                 :            :         int error;
     798                 :        749 :         error = pvconn_open(name, 0, 0, &pvconn);
     799         [ +  - ]:        749 :         if (!error) {
     800                 :        749 :             pvconns[n_pvconns++] = pvconn;
     801                 :            :         } else {
     802         [ #  # ]:          0 :             VLOG_ERR("failed to listen on %s: %s", name, ovs_strerror(error));
     803         [ #  # ]:          0 :             if (!retval) {
     804                 :          0 :                 retval = error;
     805                 :            :             }
     806                 :            :         }
     807                 :            :     }
     808                 :            : 
     809                 :        749 :     *pvconnsp = pvconns;
     810                 :        749 :     *n_pvconnsp = n_pvconns;
     811                 :            : 
     812                 :        749 :     return retval;
     813                 :            : }
     814                 :            : 
     815                 :            : /* Returns a "preference level" for snooping 'ofconn'.  A higher return value
     816                 :            :  * means that 'ofconn' is more interesting for monitoring than a lower return
     817                 :            :  * value. */
     818                 :            : static int
     819                 :          0 : snoop_preference(const struct ofconn *ofconn)
     820                 :            : {
     821   [ #  #  #  # ]:          0 :     switch (ofconn->role) {
     822                 :            :     case OFPCR12_ROLE_MASTER:
     823                 :          0 :         return 3;
     824                 :            :     case OFPCR12_ROLE_EQUAL:
     825                 :          0 :         return 2;
     826                 :            :     case OFPCR12_ROLE_SLAVE:
     827                 :          0 :         return 1;
     828                 :            :     case OFPCR12_ROLE_NOCHANGE:
     829                 :            :     default:
     830                 :            :         /* Shouldn't happen. */
     831                 :          0 :         return 0;
     832                 :            :     }
     833                 :            : }
     834                 :            : 
     835                 :            : /* One of 'mgr''s "snoop" pvconns has accepted a new connection on 'vconn'.
     836                 :            :  * Connects this vconn to a controller. */
     837                 :            : static void
     838                 :          0 : add_snooper(struct connmgr *mgr, struct vconn *vconn)
     839                 :            : {
     840                 :            :     struct ofconn *ofconn, *best;
     841                 :            : 
     842                 :            :     /* Pick a controller for monitoring. */
     843                 :          0 :     best = NULL;
     844         [ #  # ]:          0 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
     845         [ #  # ]:          0 :         if (ofconn->type == OFCONN_PRIMARY
     846 [ #  # ][ #  # ]:          0 :             && (!best || snoop_preference(ofconn) > snoop_preference(best))) {
     847                 :          0 :             best = ofconn;
     848                 :            :         }
     849                 :            :     }
     850                 :            : 
     851         [ #  # ]:          0 :     if (best) {
     852                 :          0 :         rconn_add_monitor(best->rconn, vconn);
     853                 :            :     } else {
     854         [ #  # ]:          0 :         VLOG_INFO_RL(&rl, "no controller connection to snoop");
     855                 :          0 :         vconn_close(vconn);
     856                 :            :     }
     857                 :          0 : }
     858                 :            : 
     859                 :            : /* Public ofconn functions. */
     860                 :            : 
     861                 :            : /* Returns the connection type, either OFCONN_PRIMARY or OFCONN_SERVICE. */
     862                 :            : enum ofconn_type
     863                 :      35802 : ofconn_get_type(const struct ofconn *ofconn)
     864                 :            : {
     865                 :      35802 :     return ofconn->type;
     866                 :            : }
     867                 :            : 
     868                 :            : /* If a master election id is defined, stores it into '*idp' and returns
     869                 :            :  * true.  Otherwise, stores UINT64_MAX into '*idp' and returns false. */
     870                 :            : bool
     871                 :         24 : ofconn_get_master_election_id(const struct ofconn *ofconn, uint64_t *idp)
     872                 :            : {
     873                 :         48 :     *idp = (ofconn->connmgr->master_election_id_defined
     874                 :         18 :             ? ofconn->connmgr->master_election_id
     875         [ +  + ]:         24 :             : UINT64_MAX);
     876                 :         24 :     return ofconn->connmgr->master_election_id_defined;
     877                 :            : }
     878                 :            : 
     879                 :            : /* Sets the master election id.
     880                 :            :  *
     881                 :            :  * Returns true if successful, false if the id is stale
     882                 :            :  */
     883                 :            : bool
     884                 :         18 : ofconn_set_master_election_id(struct ofconn *ofconn, uint64_t id)
     885                 :            : {
     886         [ +  + ]:         18 :     if (ofconn->connmgr->master_election_id_defined
     887         [ +  + ]:         11 :         &&
     888                 :            :         /* Unsigned difference interpreted as a two's complement signed
     889                 :            :          * value */
     890                 :         11 :         (int64_t)(id - ofconn->connmgr->master_election_id) < 0) {
     891                 :          2 :         return false;
     892                 :            :     }
     893                 :         16 :     ofconn->connmgr->master_election_id = id;
     894                 :         16 :     ofconn->connmgr->master_election_id_defined = true;
     895                 :            : 
     896                 :         16 :     return true;
     897                 :            : }
     898                 :            : 
     899                 :            : /* Returns the role configured for 'ofconn'.
     900                 :            :  *
     901                 :            :  * The default role, if no other role has been set, is OFPCR12_ROLE_EQUAL. */
     902                 :            : enum ofp12_controller_role
     903                 :         22 : ofconn_get_role(const struct ofconn *ofconn)
     904                 :            : {
     905                 :         22 :     return ofconn->role;
     906                 :            : }
     907                 :            : 
     908                 :            : void
     909                 :          2 : ofconn_send_role_status(struct ofconn *ofconn, uint32_t role, uint8_t reason)
     910                 :            : {
     911                 :            :     struct ofputil_role_status status;
     912                 :            :     struct ofpbuf *buf;
     913                 :            : 
     914                 :          2 :     status.reason = reason;
     915                 :          2 :     status.role = role;
     916                 :          2 :     ofconn_get_master_election_id(ofconn, &status.generation_id);
     917                 :            : 
     918                 :          2 :     buf = ofputil_encode_role_status(&status, ofconn_get_protocol(ofconn));
     919         [ +  + ]:          2 :     if (buf) {
     920                 :          1 :         ofconn_send(ofconn, buf, NULL);
     921                 :            :     }
     922                 :          2 : }
     923                 :            : 
     924                 :            : /* Changes 'ofconn''s role to 'role'.  If 'role' is OFPCR12_ROLE_MASTER then
     925                 :            :  * any existing master is demoted to a slave. */
     926                 :            : void
     927                 :         18 : ofconn_set_role(struct ofconn *ofconn, enum ofp12_controller_role role)
     928                 :            : {
     929 [ +  - ][ +  + ]:         18 :     if (role != ofconn->role && role == OFPCR12_ROLE_MASTER) {
     930                 :            :         struct ofconn *other;
     931                 :            : 
     932         [ +  + ]:         24 :         LIST_FOR_EACH (other, node, &ofconn->connmgr->all_conns) {
     933         [ +  + ]:         15 :             if (other->role == OFPCR12_ROLE_MASTER) {
     934                 :          2 :                 other->role = OFPCR12_ROLE_SLAVE;
     935                 :          2 :                 ofconn_send_role_status(other, OFPCR12_ROLE_SLAVE, OFPCRR_MASTER_REQUEST);
     936                 :            :             }
     937                 :            :         }
     938                 :            :     }
     939                 :         18 :     ofconn->role = role;
     940                 :         18 : }
     941                 :            : 
     942                 :            : void
     943                 :        159 : ofconn_set_invalid_ttl_to_controller(struct ofconn *ofconn, bool enable)
     944                 :            : {
     945                 :        159 :     struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
     946                 :        159 :     uint32_t bit = 1u << OFPR_INVALID_TTL;
     947         [ +  + ]:        159 :     if (enable) {
     948                 :         30 :         ac.master[OAM_PACKET_IN] |= bit;
     949                 :            :     } else {
     950                 :        129 :         ac.master[OAM_PACKET_IN] &= ~bit;
     951                 :            :     }
     952                 :        159 :     ofconn_set_async_config(ofconn, &ac);
     953                 :        159 : }
     954                 :            : 
     955                 :            : bool
     956                 :        282 : ofconn_get_invalid_ttl_to_controller(struct ofconn *ofconn)
     957                 :            : {
     958                 :        282 :     struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
     959                 :        282 :     uint32_t bit = 1u << OFPR_INVALID_TTL;
     960                 :        282 :     return (ac.master[OAM_PACKET_IN] & bit) != 0;
     961                 :            : }
     962                 :            : 
     963                 :            : /* Returns the currently configured protocol for 'ofconn', one of OFPUTIL_P_*.
     964                 :            :  *
     965                 :            :  * Returns OFPUTIL_P_NONE, which is not a valid protocol, if 'ofconn' hasn't
     966                 :            :  * completed version negotiation.  This can't happen if at least one OpenFlow
     967                 :            :  * message, other than OFPT_HELLO, has been received on the connection (such as
     968                 :            :  * in ofproto.c's message handling code), since version negotiation is a
     969                 :            :  * prerequisite for starting to receive messages.  This means that
     970                 :            :  * OFPUTIL_P_NONE is a special case that most callers need not worry about. */
     971                 :            : enum ofputil_protocol
     972                 :      38763 : ofconn_get_protocol(const struct ofconn *ofconn)
     973                 :            : {
     974   [ +  +  +  - ]:      41633 :     if (ofconn->protocol == OFPUTIL_P_NONE &&
     975                 :       2870 :         rconn_is_connected(ofconn->rconn)) {
     976                 :       2870 :         int version = rconn_get_version(ofconn->rconn);
     977         [ +  + ]:       2870 :         if (version > 0) {
     978                 :       2868 :             ofconn_set_protocol(CONST_CAST(struct ofconn *, ofconn),
     979                 :            :                                 ofputil_protocol_from_ofp_version(version));
     980                 :            :         }
     981                 :            :     }
     982                 :            : 
     983                 :      38763 :     return ofconn->protocol;
     984                 :            : }
     985                 :            : 
     986                 :            : /* Sets the protocol for 'ofconn' to 'protocol' (one of OFPUTIL_P_*).
     987                 :            :  *
     988                 :            :  * (This doesn't actually send anything to accomplish this.  Presumably the
     989                 :            :  * caller already did that.) */
     990                 :            : void
     991                 :      10202 : ofconn_set_protocol(struct ofconn *ofconn, enum ofputil_protocol protocol)
     992                 :            : {
     993                 :      10202 :     ofconn->protocol = protocol;
     994                 :      10202 : }
     995                 :            : 
     996                 :            : /* Returns the currently configured packet in format for 'ofconn', one of
     997                 :            :  * NXPIF_*.
     998                 :            :  *
     999                 :            :  * The default, if no other format has been set, is NXPIF_STANDARD. */
    1000                 :            : enum nx_packet_in_format
    1001                 :          0 : ofconn_get_packet_in_format(struct ofconn *ofconn)
    1002                 :            : {
    1003                 :          0 :     return ofconn->packet_in_format;
    1004                 :            : }
    1005                 :            : 
    1006                 :            : /* Sets the packet in format for 'ofconn' to 'packet_in_format' (one of
    1007                 :            :  * NXPIF_*). */
    1008                 :            : void
    1009                 :        211 : ofconn_set_packet_in_format(struct ofconn *ofconn,
    1010                 :            :                             enum nx_packet_in_format packet_in_format)
    1011                 :            : {
    1012                 :        211 :     ofconn->packet_in_format = packet_in_format;
    1013                 :        211 : }
    1014                 :            : 
    1015                 :            : /* Sets the controller connection ID for 'ofconn' to 'controller_id'.
    1016                 :            :  *
    1017                 :            :  * The connection controller ID is used for OFPP_CONTROLLER and
    1018                 :            :  * NXAST_CONTROLLER actions.  See "struct nx_action_controller" for details. */
    1019                 :            : void
    1020                 :          8 : ofconn_set_controller_id(struct ofconn *ofconn, uint16_t controller_id)
    1021                 :            : {
    1022                 :          8 :     ofconn->controller_id = controller_id;
    1023                 :          8 : }
    1024                 :            : 
    1025                 :            : /* Returns the default miss send length for 'ofconn'. */
    1026                 :            : int
    1027                 :        290 : ofconn_get_miss_send_len(const struct ofconn *ofconn)
    1028                 :            : {
    1029                 :        290 :     return ofconn->miss_send_len;
    1030                 :            : }
    1031                 :            : 
    1032                 :            : /* Sets the default miss send length for 'ofconn' to 'miss_send_len'. */
    1033                 :            : void
    1034                 :        218 : ofconn_set_miss_send_len(struct ofconn *ofconn, int miss_send_len)
    1035                 :            : {
    1036                 :        218 :     ofconn->miss_send_len = miss_send_len;
    1037                 :        218 : }
    1038                 :            : 
    1039                 :            : void
    1040                 :        167 : ofconn_set_async_config(struct ofconn *ofconn,
    1041                 :            :                         const struct ofputil_async_cfg *ac)
    1042                 :            : {
    1043         [ +  + ]:        167 :     if (!ofconn->async_cfg) {
    1044                 :        135 :         ofconn->async_cfg = xmalloc(sizeof *ofconn->async_cfg);
    1045                 :            :     }
    1046                 :        167 :     *ofconn->async_cfg = *ac;
    1047                 :        167 : }
    1048                 :            : 
    1049                 :            : struct ofputil_async_cfg
    1050                 :       2019 : ofconn_get_async_config(const struct ofconn *ofconn)
    1051                 :            : {
    1052         [ +  + ]:       2019 :     if (ofconn->async_cfg) {
    1053                 :        706 :         return *ofconn->async_cfg;
    1054                 :            :     }
    1055                 :            : 
    1056                 :       1313 :     int version = rconn_get_version(ofconn->rconn);
    1057         [ -  + ]:       1313 :     return (version < 0 || !ofconn->enable_async_msgs
    1058                 :            :             ? OFPUTIL_ASYNC_CFG_INIT
    1059         [ +  + ]:       1313 :             : ofputil_async_cfg_default(version));
    1060                 :            : }
    1061                 :            : 
    1062                 :            : /* Sends 'msg' on 'ofconn', accounting it as a reply.  (If there is a
    1063                 :            :  * sufficient number of OpenFlow replies in-flight on a single ofconn, then the
    1064                 :            :  * connmgr will stop accepting new OpenFlow requests on that ofconn until the
    1065                 :            :  * controller has accepted some of the replies.) */
    1066                 :            : void
    1067                 :      16938 : ofconn_send_reply(const struct ofconn *ofconn, struct ofpbuf *msg)
    1068                 :            : {
    1069                 :      16938 :     ofconn_send(ofconn, msg, ofconn->reply_counter);
    1070                 :      16938 : }
    1071                 :            : 
    1072                 :            : /* Sends each of the messages in list 'replies' on 'ofconn' in order,
    1073                 :            :  * accounting them as replies. */
    1074                 :            : void
    1075                 :        546 : ofconn_send_replies(const struct ofconn *ofconn, struct ovs_list *replies)
    1076                 :            : {
    1077                 :            :     struct ofpbuf *reply;
    1078                 :            : 
    1079         [ +  + ]:       1132 :     LIST_FOR_EACH_POP (reply, list_node, replies) {
    1080                 :        586 :         ofconn_send_reply(ofconn, reply);
    1081                 :            :     }
    1082                 :        546 : }
    1083                 :            : 
    1084                 :            : /* Sends 'error' on 'ofconn', as a reply to 'request'.  Only at most the
    1085                 :            :  * first 64 bytes of 'request' are used. */
    1086                 :            : void
    1087                 :        624 : ofconn_send_error(const struct ofconn *ofconn,
    1088                 :            :                   const struct ofp_header *request, enum ofperr error)
    1089                 :            : {
    1090                 :            :     static struct vlog_rate_limit err_rl = VLOG_RATE_LIMIT_INIT(10, 10);
    1091                 :            :     struct ofpbuf *reply;
    1092                 :            : 
    1093                 :        624 :     reply = ofperr_encode_reply(error, request);
    1094         [ +  + ]:        624 :     if (!VLOG_DROP_INFO(&err_rl)) {
    1095                 :            :         const char *type_name;
    1096                 :            :         size_t request_len;
    1097                 :            :         enum ofpraw raw;
    1098                 :            : 
    1099                 :        333 :         request_len = ntohs(request->length);
    1100                 :        333 :         type_name = (!ofpraw_decode_partial(&raw, request,
    1101                 :            :                                             MIN(64, request_len))
    1102                 :        333 :                      ? ofpraw_get_name(raw)
    1103         [ +  - ]:        333 :                      : "invalid");
    1104                 :            : 
    1105         [ +  - ]:        333 :         VLOG_INFO("%s: sending %s error reply to %s message",
    1106                 :            :                   rconn_get_name(ofconn->rconn), ofperr_to_string(error),
    1107                 :            :                   type_name);
    1108                 :            :     }
    1109                 :        624 :     ofconn_send_reply(ofconn, reply);
    1110                 :        624 : }
    1111                 :            : 
    1112                 :            : /* Reports that a flow_mod operation of the type specified by 'command' was
    1113                 :            :  * successfully executed by 'ofconn', so that the connmgr can log it. */
    1114                 :            : void
    1115                 :      33513 : ofconn_report_flow_mod(struct ofconn *ofconn,
    1116                 :            :                        enum ofp_flow_mod_command command)
    1117                 :            : {
    1118                 :            :     long long int now;
    1119                 :            : 
    1120   [ +  +  +  - ]:      33513 :     switch (command) {
    1121                 :            :     case OFPFC_ADD:
    1122                 :      26722 :         ofconn->n_add++;
    1123                 :      26722 :         break;
    1124                 :            : 
    1125                 :            :     case OFPFC_MODIFY:
    1126                 :            :     case OFPFC_MODIFY_STRICT:
    1127                 :        379 :         ofconn->n_modify++;
    1128                 :        379 :         break;
    1129                 :            : 
    1130                 :            :     case OFPFC_DELETE:
    1131                 :            :     case OFPFC_DELETE_STRICT:
    1132                 :       6412 :         ofconn->n_delete++;
    1133                 :       6412 :         break;
    1134                 :            :     }
    1135                 :            : 
    1136                 :      33513 :     now = time_msec();
    1137         [ +  + ]:      33513 :     if (ofconn->next_op_report == LLONG_MAX) {
    1138                 :       1008 :         ofconn->first_op = now;
    1139                 :       1008 :         ofconn->next_op_report = MAX(now + 10 * 1000, ofconn->op_backoff);
    1140                 :       1008 :         ofconn->op_backoff = ofconn->next_op_report + 60 * 1000;
    1141                 :            :     }
    1142                 :      33513 :     ofconn->last_op = now;
    1143                 :      33513 : }
    1144                 :            : 
    1145                 :            : /* OpenFlow 1.4 bundles. */
    1146                 :            : 
    1147                 :            : static inline uint32_t
    1148                 :       1095 : bundle_hash(uint32_t id)
    1149                 :            : {
    1150                 :       1095 :     return hash_int(id, 0);
    1151                 :            : }
    1152                 :            : 
    1153                 :            : struct ofp_bundle *
    1154                 :        968 : ofconn_get_bundle(struct ofconn *ofconn, uint32_t id)
    1155                 :            : {
    1156                 :            :     struct ofp_bundle *bundle;
    1157                 :            : 
    1158 [ +  + ][ -  + ]:        968 :     HMAP_FOR_EACH_IN_BUCKET(bundle, node, bundle_hash(id), &ofconn->bundles) {
    1159         [ +  - ]:        835 :         if (bundle->id == id) {
    1160                 :        835 :             return bundle;
    1161                 :            :         }
    1162                 :            :     }
    1163                 :            : 
    1164                 :        133 :     return NULL;
    1165                 :            : }
    1166                 :            : 
    1167                 :            : enum ofperr
    1168                 :        127 : ofconn_insert_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle)
    1169                 :            : {
    1170                 :            :     /* XXX: Check the limit of open bundles */
    1171                 :            : 
    1172                 :        127 :     hmap_insert(&ofconn->bundles, &bundle->node, bundle_hash(bundle->id));
    1173                 :            : 
    1174                 :        127 :     return 0;
    1175                 :            : }
    1176                 :            : 
    1177                 :            : enum ofperr
    1178                 :        127 : ofconn_remove_bundle(struct ofconn *ofconn, struct ofp_bundle *bundle)
    1179                 :            : {
    1180                 :        127 :     hmap_remove(&ofconn->bundles, &bundle->node);
    1181                 :            : 
    1182                 :        127 :     return 0;
    1183                 :            : }
    1184                 :            : 
    1185                 :            : static void
    1186                 :       3420 : bundle_remove_all(struct ofconn *ofconn)
    1187                 :            : {
    1188                 :            :     struct ofp_bundle *b, *next;
    1189                 :            : 
    1190 [ +  + ][ -  + ]:       3422 :     HMAP_FOR_EACH_SAFE (b, next, node, &ofconn->bundles) {
                 [ +  + ]
    1191                 :          2 :         ofp_bundle_remove__(ofconn, b, false);
    1192                 :            :     }
    1193                 :       3420 : }
    1194                 :            : 
    1195                 :            : /* Private ofconn functions. */
    1196                 :            : 
    1197                 :            : static const char *
    1198                 :          1 : ofconn_get_target(const struct ofconn *ofconn)
    1199                 :            : {
    1200                 :          1 :     return rconn_get_target(ofconn->rconn);
    1201                 :            : }
    1202                 :            : 
    1203                 :            : static struct ofconn *
    1204                 :       3420 : ofconn_create(struct connmgr *mgr, struct rconn *rconn, enum ofconn_type type,
    1205                 :            :               bool enable_async_msgs)
    1206                 :            : {
    1207                 :            :     struct ofconn *ofconn;
    1208                 :            : 
    1209                 :       3420 :     ofconn = xzalloc(sizeof *ofconn);
    1210                 :       3420 :     ofconn->connmgr = mgr;
    1211                 :       3420 :     ovs_list_push_back(&mgr->all_conns, &ofconn->node);
    1212                 :       3420 :     ofconn->rconn = rconn;
    1213                 :       3420 :     ofconn->type = type;
    1214                 :       3420 :     ofconn->enable_async_msgs = enable_async_msgs;
    1215                 :            : 
    1216                 :       3420 :     hmap_init(&ofconn->monitors);
    1217                 :       3420 :     ovs_list_init(&ofconn->updates);
    1218                 :            : 
    1219                 :       3420 :     hmap_init(&ofconn->bundles);
    1220                 :            : 
    1221                 :       3420 :     ofconn_flush(ofconn);
    1222                 :            : 
    1223                 :       3420 :     return ofconn;
    1224                 :            : }
    1225                 :            : 
    1226                 :            : /* Clears all of the state in 'ofconn' that should not persist from one
    1227                 :            :  * connection to the next. */
    1228                 :            : static void
    1229                 :       6888 : ofconn_flush(struct ofconn *ofconn)
    1230                 :            :     OVS_REQUIRES(ofproto_mutex)
    1231                 :            : {
    1232                 :            :     struct ofmonitor *monitor, *next_monitor;
    1233                 :            :     int i;
    1234                 :            : 
    1235                 :       6888 :     ofconn_log_flow_mods(ofconn);
    1236                 :            : 
    1237                 :       6888 :     ofconn->role = OFPCR12_ROLE_EQUAL;
    1238                 :       6888 :     ofconn_set_protocol(ofconn, OFPUTIL_P_NONE);
    1239                 :       6888 :     ofconn->packet_in_format = NXPIF_STANDARD;
    1240                 :            : 
    1241                 :       6888 :     rconn_packet_counter_destroy(ofconn->packet_in_counter);
    1242                 :       6888 :     ofconn->packet_in_counter = rconn_packet_counter_create();
    1243         [ +  + ]:      20664 :     for (i = 0; i < N_SCHEDULERS; i++) {
    1244         [ -  + ]:      13776 :         if (ofconn->schedulers[i]) {
    1245                 :            :             int rate, burst;
    1246                 :            : 
    1247                 :          0 :             pinsched_get_limits(ofconn->schedulers[i], &rate, &burst);
    1248                 :          0 :             pinsched_destroy(ofconn->schedulers[i]);
    1249                 :          0 :             ofconn->schedulers[i] = pinsched_create(rate, burst);
    1250                 :            :         }
    1251                 :            :     }
    1252                 :      13776 :     ofconn->miss_send_len = (ofconn->type == OFCONN_PRIMARY
    1253                 :            :                              ? OFP_DEFAULT_MISS_SEND_LEN
    1254         [ +  + ]:       6888 :                              : 0);
    1255                 :       6888 :     ofconn->controller_id = 0;
    1256                 :            : 
    1257                 :       6888 :     rconn_packet_counter_destroy(ofconn->reply_counter);
    1258                 :       6888 :     ofconn->reply_counter = rconn_packet_counter_create();
    1259                 :            : 
    1260                 :       6888 :     free(ofconn->async_cfg);
    1261                 :       6888 :     ofconn->async_cfg = NULL;
    1262                 :            : 
    1263                 :       6888 :     ofconn->n_add = ofconn->n_delete = ofconn->n_modify = 0;
    1264                 :       6888 :     ofconn->first_op = ofconn->last_op = LLONG_MIN;
    1265                 :       6888 :     ofconn->next_op_report = LLONG_MAX;
    1266                 :       6888 :     ofconn->op_backoff = LLONG_MIN;
    1267                 :            : 
    1268 [ +  + ][ -  + ]:       6892 :     HMAP_FOR_EACH_SAFE (monitor, next_monitor, ofconn_node,
                 [ +  + ]
    1269                 :            :                         &ofconn->monitors) {
    1270                 :          4 :         ofmonitor_destroy(monitor);
    1271                 :            :     }
    1272                 :       6888 :     rconn_packet_counter_destroy(ofconn->monitor_counter);
    1273                 :       6888 :     ofconn->monitor_counter = rconn_packet_counter_create();
    1274                 :       6888 :     ofpbuf_list_delete(&ofconn->updates); /* ...but it should be empty. */
    1275                 :       6888 : }
    1276                 :            : 
    1277                 :            : static void
    1278                 :       3420 : ofconn_destroy(struct ofconn *ofconn)
    1279                 :            :     OVS_REQUIRES(ofproto_mutex)
    1280                 :            : {
    1281                 :       3420 :     ofconn_flush(ofconn);
    1282                 :            : 
    1283         [ +  + ]:       3420 :     if (ofconn->type == OFCONN_PRIMARY) {
    1284                 :          1 :         hmap_remove(&ofconn->connmgr->controllers, &ofconn->hmap_node);
    1285                 :            :     }
    1286                 :            : 
    1287                 :       3420 :     bundle_remove_all(ofconn);
    1288                 :       3420 :     hmap_destroy(&ofconn->bundles);
    1289                 :            : 
    1290                 :       3420 :     hmap_destroy(&ofconn->monitors);
    1291                 :       3420 :     ovs_list_remove(&ofconn->node);
    1292                 :       3420 :     rconn_destroy(ofconn->rconn);
    1293                 :       3420 :     rconn_packet_counter_destroy(ofconn->packet_in_counter);
    1294                 :       3420 :     rconn_packet_counter_destroy(ofconn->reply_counter);
    1295                 :       3420 :     rconn_packet_counter_destroy(ofconn->monitor_counter);
    1296                 :       3420 :     free(ofconn);
    1297                 :       3420 : }
    1298                 :            : 
    1299                 :            : /* Reconfigures 'ofconn' to match 'c'.  'ofconn' and 'c' must have the same
    1300                 :            :  * target. */
    1301                 :            : static void
    1302                 :          1 : ofconn_reconfigure(struct ofconn *ofconn, const struct ofproto_controller *c)
    1303                 :            : {
    1304                 :            :     int probe_interval;
    1305                 :            : 
    1306                 :          1 :     ofconn->band = c->band;
    1307                 :          1 :     ofconn->enable_async_msgs = c->enable_async_msgs;
    1308                 :            : 
    1309                 :          1 :     rconn_set_max_backoff(ofconn->rconn, c->max_backoff);
    1310                 :            : 
    1311         [ +  - ]:          1 :     probe_interval = c->probe_interval ? MAX(c->probe_interval, 5) : 0;
    1312                 :          1 :     rconn_set_probe_interval(ofconn->rconn, probe_interval);
    1313                 :            : 
    1314                 :          1 :     ofconn_set_rate_limit(ofconn, c->rate_limit, c->burst_limit);
    1315                 :            : 
    1316                 :            :     /* If dscp value changed reconnect. */
    1317         [ -  + ]:          1 :     if (c->dscp != rconn_get_dscp(ofconn->rconn)) {
    1318                 :          0 :         rconn_set_dscp(ofconn->rconn, c->dscp);
    1319                 :          0 :         rconn_reconnect(ofconn->rconn);
    1320                 :            :     }
    1321                 :          1 : }
    1322                 :            : 
    1323                 :            : /* Returns true if it makes sense for 'ofconn' to receive and process OpenFlow
    1324                 :            :  * messages. */
    1325                 :            : static bool
    1326                 :     259682 : ofconn_may_recv(const struct ofconn *ofconn)
    1327                 :            : {
    1328                 :     259682 :     int count = rconn_packet_counter_n_packets(ofconn->reply_counter);
    1329                 :     259682 :     return count < OFCONN_REPLY_MAX;
    1330                 :            : }
    1331                 :            : 
    1332                 :            : static void
    1333                 :     104006 : ofconn_run(struct ofconn *ofconn,
    1334                 :            :            void (*handle_openflow)(struct ofconn *,
    1335                 :            :                                    const struct ofpbuf *ofp_msg))
    1336                 :            : {
    1337                 :     104006 :     struct connmgr *mgr = ofconn->connmgr;
    1338                 :            :     size_t i;
    1339                 :            : 
    1340         [ +  + ]:     312018 :     for (i = 0; i < N_SCHEDULERS; i++) {
    1341                 :            :         struct ovs_list txq;
    1342                 :            : 
    1343                 :     208012 :         pinsched_run(ofconn->schedulers[i], &txq);
    1344                 :     208012 :         do_send_packet_ins(ofconn, &txq);
    1345                 :            :     }
    1346                 :            : 
    1347                 :     104006 :     rconn_run(ofconn->rconn);
    1348                 :            : 
    1349                 :            :     /* Limit the number of iterations to avoid starving other tasks. */
    1350 [ +  + ][ +  - ]:     156725 :     for (i = 0; i < 50 && ofconn_may_recv(ofconn); i++) {
    1351                 :     156406 :         struct ofpbuf *of_msg = rconn_recv(ofconn->rconn);
    1352         [ +  + ]:     156406 :         if (!of_msg) {
    1353                 :     103687 :             break;
    1354                 :            :         }
    1355                 :            : 
    1356         [ -  + ]:      52719 :         if (mgr->fail_open) {
    1357                 :          0 :             fail_open_maybe_recover(mgr->fail_open);
    1358                 :            :         }
    1359                 :            : 
    1360                 :      52719 :         handle_openflow(ofconn, of_msg);
    1361                 :      52719 :         ofpbuf_delete(of_msg);
    1362                 :            :     }
    1363                 :            : 
    1364         [ +  + ]:     104006 :     if (time_msec() >= ofconn->next_op_report) {
    1365                 :         16 :         ofconn_log_flow_mods(ofconn);
    1366                 :            :     }
    1367                 :            : 
    1368                 :     104006 :     ovs_mutex_lock(&ofproto_mutex);
    1369         [ +  + ]:     104006 :     if (!rconn_is_alive(ofconn->rconn)) {
    1370                 :       3390 :         ofconn_destroy(ofconn);
    1371         [ +  + ]:     100616 :     } else if (!rconn_is_connected(ofconn->rconn)) {
    1372                 :         48 :         ofconn_flush(ofconn);
    1373                 :            :     }
    1374                 :     104006 :     ovs_mutex_unlock(&ofproto_mutex);
    1375                 :     104006 : }
    1376                 :            : 
    1377                 :            : static void
    1378                 :     103276 : ofconn_wait(struct ofconn *ofconn)
    1379                 :            : {
    1380                 :            :     int i;
    1381                 :            : 
    1382         [ +  + ]:     309828 :     for (i = 0; i < N_SCHEDULERS; i++) {
    1383                 :     206552 :         pinsched_wait(ofconn->schedulers[i]);
    1384                 :            :     }
    1385                 :     103276 :     rconn_run_wait(ofconn->rconn);
    1386         [ +  - ]:     103276 :     if (ofconn_may_recv(ofconn)) {
    1387                 :     103276 :         rconn_recv_wait(ofconn->rconn);
    1388                 :            :     }
    1389         [ +  + ]:     103276 :     if (ofconn->next_op_report != LLONG_MAX) {
    1390                 :      33362 :         poll_timer_wait_until(ofconn->next_op_report);
    1391                 :            :     }
    1392                 :     103276 : }
    1393                 :            : 
    1394                 :            : static void
    1395                 :       6904 : ofconn_log_flow_mods(struct ofconn *ofconn)
    1396                 :            : {
    1397                 :       6904 :     int n_flow_mods = ofconn->n_add + ofconn->n_delete + ofconn->n_modify;
    1398         [ +  + ]:       6904 :     if (n_flow_mods) {
    1399                 :       1008 :         long long int ago = (time_msec() - ofconn->first_op) / 1000;
    1400                 :       1008 :         long long int interval = (ofconn->last_op - ofconn->first_op) / 1000;
    1401                 :            :         struct ds s;
    1402                 :            : 
    1403                 :       1008 :         ds_init(&s);
    1404                 :       1008 :         ds_put_format(&s, "%d flow_mods ", n_flow_mods);
    1405         [ +  + ]:       1008 :         if (interval == ago) {
    1406                 :        963 :             ds_put_format(&s, "in the last %lld s", ago);
    1407         [ +  + ]:         45 :         } else if (interval) {
    1408                 :         31 :             ds_put_format(&s, "in the %lld s starting %lld s ago",
    1409                 :            :                           interval, ago);
    1410                 :            :         } else {
    1411                 :         14 :             ds_put_format(&s, "%lld s ago", ago);
    1412                 :            :         }
    1413                 :            : 
    1414                 :       1008 :         ds_put_cstr(&s, " (");
    1415         [ +  + ]:       1008 :         if (ofconn->n_add) {
    1416                 :        777 :             ds_put_format(&s, "%d adds, ", ofconn->n_add);
    1417                 :            :         }
    1418         [ +  + ]:       1008 :         if (ofconn->n_delete) {
    1419                 :        256 :             ds_put_format(&s, "%d deletes, ", ofconn->n_delete);
    1420                 :            :         }
    1421         [ +  + ]:       1008 :         if (ofconn->n_modify) {
    1422                 :         82 :             ds_put_format(&s, "%d modifications, ", ofconn->n_modify);
    1423                 :            :         }
    1424                 :       1008 :         s.length -= 2;
    1425                 :       1008 :         ds_put_char(&s, ')');
    1426                 :            : 
    1427         [ +  - ]:       1008 :         VLOG_INFO("%s: %s", rconn_get_name(ofconn->rconn), ds_cstr(&s));
    1428                 :       1008 :         ds_destroy(&s);
    1429                 :            : 
    1430                 :       1008 :         ofconn->n_add = ofconn->n_delete = ofconn->n_modify = 0;
    1431                 :            :     }
    1432                 :       6904 :     ofconn->next_op_report = LLONG_MAX;
    1433                 :       6904 : }
    1434                 :            : 
    1435                 :            : /* Returns true if 'ofconn' should receive asynchronous messages of the given
    1436                 :            :  * OAM_* 'type' and 'reason', which should be a OFPR_* value for OAM_PACKET_IN,
    1437                 :            :  * a OFPPR_* value for OAM_PORT_STATUS, or an OFPRR_* value for
    1438                 :            :  * OAM_FLOW_REMOVED.  Returns false if the message should not be sent on
    1439                 :            :  * 'ofconn'. */
    1440                 :            : static bool
    1441                 :       2986 : ofconn_receives_async_msg(const struct ofconn *ofconn,
    1442                 :            :                           enum ofputil_async_msg_type type,
    1443                 :            :                           unsigned int reason)
    1444                 :            : {
    1445         [ -  + ]:       2986 :     ovs_assert(reason < 32);
    1446         [ -  + ]:       2986 :     ovs_assert((unsigned int) type < OAM_N_TYPES);
    1447                 :            : 
    1448                 :            :     /* Keep the following code in sync with the documentation in the
    1449                 :            :      * "Asynchronous Messages" section in DESIGN. */
    1450                 :            : 
    1451 [ +  + ][ +  + ]:       2986 :     if (ofconn->type == OFCONN_SERVICE && !ofconn->miss_send_len) {
    1452                 :            :         /* Service connections don't get asynchronous messages unless they have
    1453                 :            :          * explicitly asked for them by setting a nonzero miss send length. */
    1454                 :       1417 :         return false;
    1455                 :            :     }
    1456                 :            : 
    1457                 :       1569 :     struct ofputil_async_cfg ac = ofconn_get_async_config(ofconn);
    1458                 :       3138 :     uint32_t *masks = (ofconn->role == OFPCR12_ROLE_SLAVE
    1459                 :            :                        ? ac.slave
    1460         [ +  + ]:       1569 :                        : ac.master);
    1461                 :       2986 :     return (masks[type] & (1u << reason)) != 0;
    1462                 :            : }
    1463                 :            : 
    1464                 :            : /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
    1465                 :            :  * packet rather than to send the packet to the controller.
    1466                 :            :  *
    1467                 :            :  * This function returns true to indicate that a packet_in message
    1468                 :            :  * for a "table-miss" should be sent to at least one controller.
    1469                 :            :  * That is there is at least one controller with controller_id 0
    1470                 :            :  * which connected using an OpenFlow version earlier than OpenFlow1.3.
    1471                 :            :  *
    1472                 :            :  * False otherwise.
    1473                 :            :  *
    1474                 :            :  * This logic assumes that "table-miss" packet_in messages
    1475                 :            :  * are always sent to controller_id 0. */
    1476                 :            : bool
    1477                 :       3904 : connmgr_wants_packet_in_on_miss(struct connmgr *mgr) OVS_EXCLUDED(ofproto_mutex)
    1478                 :            : {
    1479                 :            :     struct ofconn *ofconn;
    1480                 :            : 
    1481                 :       3904 :     ovs_mutex_lock(&ofproto_mutex);
    1482         [ +  + ]:       4905 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1483                 :       1135 :         enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
    1484                 :            : 
    1485 [ +  - ][ +  + ]:       1135 :         if (ofconn->controller_id == 0 &&
    1486         [ +  + ]:       1134 :             (protocol == OFPUTIL_P_NONE ||
    1487                 :       1134 :              ofputil_protocol_to_ofp_version(protocol) < OFP13_VERSION)) {
    1488                 :        134 :             ovs_mutex_unlock(&ofproto_mutex);
    1489                 :        134 :             return true;
    1490                 :            :         }
    1491                 :            :     }
    1492                 :       3770 :     ovs_mutex_unlock(&ofproto_mutex);
    1493                 :            : 
    1494                 :       3770 :     return false;
    1495                 :            : }
    1496                 :            : 
    1497                 :            : /* Returns a human-readable name for an OpenFlow connection between 'mgr' and
    1498                 :            :  * 'target', suitable for use in log messages for identifying the connection.
    1499                 :            :  *
    1500                 :            :  * The name is dynamically allocated.  The caller should free it (with free())
    1501                 :            :  * when it is no longer needed. */
    1502                 :            : static char *
    1503                 :       3420 : ofconn_make_name(const struct connmgr *mgr, const char *target)
    1504                 :            : {
    1505                 :       3420 :     return xasprintf("%s<->%s", mgr->name, target);
    1506                 :            : }
    1507                 :            : 
    1508                 :            : static void
    1509                 :       3420 : ofconn_set_rate_limit(struct ofconn *ofconn, int rate, int burst)
    1510                 :            : {
    1511                 :            :     int i;
    1512                 :            : 
    1513         [ +  + ]:      10260 :     for (i = 0; i < N_SCHEDULERS; i++) {
    1514                 :       6840 :         struct pinsched **s = &ofconn->schedulers[i];
    1515                 :            : 
    1516         [ -  + ]:       6840 :         if (rate > 0) {
    1517         [ #  # ]:          0 :             if (!*s) {
    1518                 :          0 :                 *s = pinsched_create(rate, burst);
    1519                 :            :             } else {
    1520                 :          0 :                 pinsched_set_limits(*s, rate, burst);
    1521                 :            :             }
    1522                 :            :         } else {
    1523                 :       6840 :             pinsched_destroy(*s);
    1524                 :       6840 :             *s = NULL;
    1525                 :            :         }
    1526                 :            :     }
    1527                 :       3420 : }
    1528                 :            : 
    1529                 :            : static void
    1530                 :      20061 : ofconn_send(const struct ofconn *ofconn, struct ofpbuf *msg,
    1531                 :            :             struct rconn_packet_counter *counter)
    1532                 :            : {
    1533                 :      20061 :     ofpmsg_update_length(msg);
    1534                 :      20061 :     rconn_send(ofconn->rconn, msg, counter);
    1535                 :      20061 : }
    1536                 :            : 
    1537                 :            : /* Sending asynchronous messages. */
    1538                 :            : 
    1539                 :            : /* Sends an OFPT_PORT_STATUS message with 'opp' and 'reason' to appropriate
    1540                 :            :  * controllers managed by 'mgr'.  For messages caused by a controller
    1541                 :            :  * OFPT_PORT_MOD, specify 'source' as the controller connection that sent the
    1542                 :            :  * request; otherwise, specify 'source' as NULL. */
    1543                 :            : void
    1544                 :       4050 : connmgr_send_port_status(struct connmgr *mgr, struct ofconn *source,
    1545                 :            :                          const struct ofputil_phy_port *pp, uint8_t reason)
    1546                 :            : {
    1547                 :            :     /* XXX Should limit the number of queued port status change messages. */
    1548                 :            :     struct ofputil_port_status ps;
    1549                 :            :     struct ofconn *ofconn;
    1550                 :            : 
    1551                 :       4050 :     ps.reason = reason;
    1552                 :       4050 :     ps.desc = *pp;
    1553         [ +  + ]:       5173 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1554         [ +  + ]:       1123 :         if (ofconn_receives_async_msg(ofconn, OAM_PORT_STATUS, reason)) {
    1555                 :            :             struct ofpbuf *msg;
    1556                 :            : 
    1557                 :            :             /* Before 1.5, OpenFlow specified that OFPT_PORT_MOD should not
    1558                 :            :              * generate OFPT_PORT_STATUS messages.  That requirement was a
    1559                 :            :              * relic of how OpenFlow originally supported a single controller,
    1560                 :            :              * so that one could expect the controller to already know the
    1561                 :            :              * changes it had made.
    1562                 :            :              *
    1563                 :            :              * EXT-338 changes OpenFlow 1.5 OFPT_PORT_MOD to send
    1564                 :            :              * OFPT_PORT_STATUS messages to every controller.  This is
    1565                 :            :              * obviously more useful in the multi-controller case.  We could
    1566                 :            :              * always implement it that way in OVS, but that would risk
    1567                 :            :              * confusing controllers that are intended for single-controller
    1568                 :            :              * use only.  (Imagine a controller that generates an OFPT_PORT_MOD
    1569                 :            :              * in response to any OFPT_PORT_STATUS!)
    1570                 :            :              *
    1571                 :            :              * So this compromises: for OpenFlow 1.4 and earlier, it generates
    1572                 :            :              * OFPT_PORT_STATUS for OFPT_PORT_MOD, but not back to the
    1573                 :            :              * originating controller.  In a single-controller environment, in
    1574                 :            :              * particular, this means that it will never generate
    1575                 :            :              * OFPT_PORT_STATUS for OFPT_PORT_MOD at all. */
    1576         [ -  + ]:        458 :             if (ofconn == source
    1577         [ #  # ]:          0 :                 && rconn_get_version(ofconn->rconn) < OFP15_VERSION) {
    1578                 :          0 :                 continue;
    1579                 :            :             }
    1580                 :            : 
    1581                 :        458 :             msg = ofputil_encode_port_status(&ps, ofconn_get_protocol(ofconn));
    1582                 :        458 :             ofconn_send(ofconn, msg, NULL);
    1583                 :            :         }
    1584                 :            :     }
    1585                 :       4050 : }
    1586                 :            : 
    1587                 :            : /* Sends an OFPT_REQUESTFORWARD message with 'request' and 'reason' to
    1588                 :            :  * appropriate controllers managed by 'mgr'.  For messages caused by a
    1589                 :            :  * controller OFPT_GROUP_MOD and OFPT_METER_MOD, specify 'source' as the
    1590                 :            :  * controller connection that sent the request; otherwise, specify 'source'
    1591                 :            :  * as NULL. */
    1592                 :            : void
    1593                 :        176 : connmgr_send_requestforward(struct connmgr *mgr, const struct ofconn *source,
    1594                 :            :                             const struct ofputil_requestforward *rf)
    1595                 :            : {
    1596                 :            :     struct ofconn *ofconn;
    1597                 :            : 
    1598         [ +  + ]:        409 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1599         [ +  + ]:        233 :         if (ofconn_receives_async_msg(ofconn, OAM_REQUESTFORWARD, rf->reason)
    1600         [ +  - ]:          6 :             && rconn_get_version(ofconn->rconn) >= OFP14_VERSION
    1601         [ +  + ]:          6 :             && ofconn != source) {
    1602                 :          4 :             enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
    1603                 :          4 :             ofconn_send(ofconn, ofputil_encode_requestforward(rf, protocol),
    1604                 :            :                         NULL);
    1605                 :            :         }
    1606                 :            :     }
    1607                 :        176 : }
    1608                 :            : 
    1609                 :            : /* Sends an OFPT_FLOW_REMOVED or NXT_FLOW_REMOVED message based on 'fr' to
    1610                 :            :  * appropriate controllers managed by 'mgr'. */
    1611                 :            : void
    1612                 :         38 : connmgr_send_flow_removed(struct connmgr *mgr,
    1613                 :            :                           const struct ofputil_flow_removed *fr)
    1614                 :            : {
    1615                 :            :     struct ofconn *ofconn;
    1616                 :            : 
    1617         [ +  + ]:        113 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1618         [ +  + ]:         75 :         if (ofconn_receives_async_msg(ofconn, OAM_FLOW_REMOVED, fr->reason)) {
    1619                 :            :             struct ofpbuf *msg;
    1620                 :            : 
    1621                 :            :             /* Account flow expirations as replies to OpenFlow requests.  That
    1622                 :            :              * works because preventing OpenFlow requests from being processed
    1623                 :            :              * also prevents new flows from being added (and expiring).  (It
    1624                 :            :              * also prevents processing OpenFlow requests that would not add
    1625                 :            :              * new flows, so it is imperfect.) */
    1626                 :         18 :             msg = ofputil_encode_flow_removed(fr, ofconn_get_protocol(ofconn));
    1627                 :         18 :             ofconn_send_reply(ofconn, msg);
    1628                 :            :         }
    1629                 :            :     }
    1630                 :         38 : }
    1631                 :            : 
    1632                 :            : /* Sends an OFPT_TABLE_STATUS message with 'reason' to appropriate controllers
    1633                 :            :  * managed by 'mgr'. When the table state changes, the controller needs to be
    1634                 :            :  * informed with the OFPT_TABLE_STATUS message. The reason values
    1635                 :            :  * OFPTR_VACANCY_DOWN and OFPTR_VACANCY_UP identify a vacancy message. The
    1636                 :            :  * vacancy events are generated when the remaining space in the flow table
    1637                 :            :  * changes and crosses one of the vacancy thereshold specified by
    1638                 :            :  * OFPT_TABLE_MOD. */
    1639                 :            : void
    1640                 :          3 : connmgr_send_table_status(struct connmgr *mgr,
    1641                 :            :                           const struct ofputil_table_desc *td,
    1642                 :            :                           uint8_t reason)
    1643                 :            : {
    1644                 :            :     struct ofputil_table_status ts;
    1645                 :            :     struct ofconn *ofconn;
    1646                 :            : 
    1647                 :          3 :     ts.reason = reason;
    1648                 :          3 :     ts.desc = *td;
    1649                 :            : 
    1650         [ +  + ]:          9 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1651         [ +  + ]:          6 :         if (ofconn_receives_async_msg(ofconn, OAM_TABLE_STATUS, reason)) {
    1652                 :            :             struct ofpbuf *msg;
    1653                 :            : 
    1654                 :          3 :             msg = ofputil_encode_table_status(&ts,
    1655                 :            :                                               ofconn_get_protocol(ofconn));
    1656         [ +  - ]:          3 :             if (msg) {
    1657                 :          3 :                 ofconn_send(ofconn, msg, NULL);
    1658                 :            :             }
    1659                 :            :         }
    1660                 :            :     }
    1661                 :          3 : }
    1662                 :            : 
    1663                 :            : /* Given 'pin', sends an OFPT_PACKET_IN message to each OpenFlow controller as
    1664                 :            :  * necessary according to their individual configurations. */
    1665                 :            : void
    1666                 :       1051 : connmgr_send_async_msg(struct connmgr *mgr,
    1667                 :            :                        const struct ofproto_async_msg *am)
    1668                 :            : {
    1669                 :            :     struct ofconn *ofconn;
    1670                 :            : 
    1671         [ +  + ]:       2656 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    1672                 :       1605 :         enum ofputil_protocol protocol = ofconn_get_protocol(ofconn);
    1673 [ +  + ][ +  - ]:       1605 :         if (protocol == OFPUTIL_P_NONE || !rconn_is_connected(ofconn->rconn)
    1674         [ +  + ]:       1604 :             || ofconn->controller_id != am->controller_id
    1675         [ +  + ]:       1549 :             || !ofconn_receives_async_msg(ofconn, am->oam,
    1676                 :       1549 :                                           am->pin.up.public.reason)) {
    1677                 :        614 :             continue;
    1678                 :            :         }
    1679                 :            : 
    1680                 :        991 :         struct ofpbuf *msg = ofputil_encode_packet_in_private(
    1681                 :            :             &am->pin.up, protocol, ofconn->packet_in_format);
    1682                 :            : 
    1683                 :            :         struct ovs_list txq;
    1684         [ +  + ]:        987 :         bool is_miss = (am->pin.up.public.reason == OFPR_NO_MATCH ||
    1685 [ +  + ][ +  + ]:       1978 :                         am->pin.up.public.reason == OFPR_EXPLICIT_MISS ||
    1686                 :        975 :                         am->pin.up.public.reason == OFPR_IMPLICIT_MISS);
    1687                 :        991 :         pinsched_send(ofconn->schedulers[is_miss],
    1688                 :            :                       am->pin.up.public.flow_metadata.flow.in_port.ofp_port,
    1689                 :            :                       msg, &txq);
    1690                 :        991 :         do_send_packet_ins(ofconn, &txq);
    1691                 :            :     }
    1692                 :       1051 : }
    1693                 :            : 
    1694                 :            : static void
    1695                 :     209003 : do_send_packet_ins(struct ofconn *ofconn, struct ovs_list *txq)
    1696                 :            : {
    1697                 :            :     struct ofpbuf *pin;
    1698                 :            : 
    1699         [ +  + ]:     209994 :     LIST_FOR_EACH_POP (pin, list_node, txq) {
    1700         [ -  + ]:        991 :         if (rconn_send_with_limit(ofconn->rconn, pin,
    1701                 :            :                                   ofconn->packet_in_counter, 100) == EAGAIN) {
    1702                 :            :             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
    1703                 :            : 
    1704         [ #  # ]:          0 :             VLOG_INFO_RL(&rl, "%s: dropping packet-in due to queue overflow",
    1705                 :            :                          rconn_get_name(ofconn->rconn));
    1706                 :            :         }
    1707                 :            :     }
    1708                 :     209003 : }
    1709                 :            : 
    1710                 :            : /* Fail-open settings. */
    1711                 :            : 
    1712                 :            : /* Returns the failure handling mode (OFPROTO_FAIL_SECURE or
    1713                 :            :  * OFPROTO_FAIL_STANDALONE) for 'mgr'. */
    1714                 :            : enum ofproto_fail_mode
    1715                 :          0 : connmgr_get_fail_mode(const struct connmgr *mgr)
    1716                 :            : {
    1717                 :          0 :     return mgr->fail_mode;
    1718                 :            : }
    1719                 :            : 
    1720                 :            : /* Sets the failure handling mode for 'mgr' to 'fail_mode' (either
    1721                 :            :  * OFPROTO_FAIL_SECURE or OFPROTO_FAIL_STANDALONE). */
    1722                 :            : void
    1723                 :       4700 : connmgr_set_fail_mode(struct connmgr *mgr, enum ofproto_fail_mode fail_mode)
    1724                 :            : {
    1725         [ +  + ]:       4700 :     if (mgr->fail_mode != fail_mode) {
    1726                 :        145 :         mgr->fail_mode = fail_mode;
    1727                 :        145 :         update_fail_open(mgr);
    1728         [ +  - ]:        145 :         if (!connmgr_has_controllers(mgr)) {
    1729                 :        145 :             ofproto_flush_flows(mgr->ofproto);
    1730                 :            :         }
    1731                 :            :     }
    1732                 :       4700 : }
    1733                 :            : 
    1734                 :            : /* Fail-open implementation. */
    1735                 :            : 
    1736                 :            : /* Returns the longest probe interval among the primary controllers configured
    1737                 :            :  * on 'mgr'.  Returns 0 if there are no primary controllers. */
    1738                 :            : int
    1739                 :          0 : connmgr_get_max_probe_interval(const struct connmgr *mgr)
    1740                 :            : {
    1741                 :            :     const struct ofconn *ofconn;
    1742                 :            :     int max_probe_interval;
    1743                 :            : 
    1744                 :          0 :     max_probe_interval = 0;
    1745 [ #  # ][ #  # ]:          0 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
    1746                 :          0 :         int probe_interval = rconn_get_probe_interval(ofconn->rconn);
    1747                 :          0 :         max_probe_interval = MAX(max_probe_interval, probe_interval);
    1748                 :            :     }
    1749                 :          0 :     return max_probe_interval;
    1750                 :            : }
    1751                 :            : 
    1752                 :            : /* Returns the number of seconds for which all of 'mgr's primary controllers
    1753                 :            :  * have been disconnected.  Returns 0 if 'mgr' has no primary controllers. */
    1754                 :            : int
    1755                 :          0 : connmgr_failure_duration(const struct connmgr *mgr)
    1756                 :            : {
    1757                 :            :     const struct ofconn *ofconn;
    1758                 :            :     int min_failure_duration;
    1759                 :            : 
    1760         [ #  # ]:          0 :     if (!connmgr_has_controllers(mgr)) {
    1761                 :          0 :         return 0;
    1762                 :            :     }
    1763                 :            : 
    1764                 :          0 :     min_failure_duration = INT_MAX;
    1765 [ #  # ][ #  # ]:          0 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
    1766                 :          0 :         int failure_duration = rconn_failure_duration(ofconn->rconn);
    1767                 :          0 :         min_failure_duration = MIN(min_failure_duration, failure_duration);
    1768                 :            :     }
    1769                 :          0 :     return min_failure_duration;
    1770                 :            : }
    1771                 :            : 
    1772                 :            : /* Returns true if at least one primary controller is connected (regardless of
    1773                 :            :  * whether those controllers are believed to have authenticated and accepted
    1774                 :            :  * this switch), false if none of them are connected. */
    1775                 :            : bool
    1776                 :          0 : connmgr_is_any_controller_connected(const struct connmgr *mgr)
    1777                 :            : {
    1778                 :            :     const struct ofconn *ofconn;
    1779                 :            : 
    1780 [ #  # ][ #  # ]:          0 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
    1781         [ #  # ]:          0 :         if (rconn_is_connected(ofconn->rconn)) {
    1782                 :          0 :             return true;
    1783                 :            :         }
    1784                 :            :     }
    1785                 :          0 :     return false;
    1786                 :            : }
    1787                 :            : 
    1788                 :            : /* Returns true if at least one primary controller is believed to have
    1789                 :            :  * authenticated and accepted this switch, false otherwise. */
    1790                 :            : bool
    1791                 :          0 : connmgr_is_any_controller_admitted(const struct connmgr *mgr)
    1792                 :            : {
    1793                 :            :     const struct ofconn *ofconn;
    1794                 :            : 
    1795 [ #  # ][ #  # ]:          0 :     HMAP_FOR_EACH (ofconn, hmap_node, &mgr->controllers) {
    1796         [ #  # ]:          0 :         if (rconn_is_admitted(ofconn->rconn)) {
    1797                 :          0 :             return true;
    1798                 :            :         }
    1799                 :            :     }
    1800                 :          0 :     return false;
    1801                 :            : }
    1802                 :            : 
    1803                 :            : /* In-band configuration. */
    1804                 :            : 
    1805                 :            : static bool any_extras_changed(const struct connmgr *,
    1806                 :            :                                const struct sockaddr_in *extras, size_t n);
    1807                 :            : 
    1808                 :            : /* Sets the 'n' TCP port addresses in 'extras' as ones to which 'mgr''s
    1809                 :            :  * in-band control should guarantee access, in the same way that in-band
    1810                 :            :  * control guarantees access to OpenFlow controllers. */
    1811                 :            : void
    1812                 :       4700 : connmgr_set_extra_in_band_remotes(struct connmgr *mgr,
    1813                 :            :                                   const struct sockaddr_in *extras, size_t n)
    1814                 :            : {
    1815         [ +  - ]:       4700 :     if (!any_extras_changed(mgr, extras, n)) {
    1816                 :       4700 :         return;
    1817                 :            :     }
    1818                 :            : 
    1819                 :          0 :     free(mgr->extra_in_band_remotes);
    1820                 :          0 :     mgr->n_extra_remotes = n;
    1821                 :          0 :     mgr->extra_in_band_remotes = xmemdup(extras, n * sizeof *extras);
    1822                 :            : 
    1823                 :          0 :     update_in_band_remotes(mgr);
    1824                 :            : }
    1825                 :            : 
    1826                 :            : /* Sets the OpenFlow queue used by flows set up by in-band control on
    1827                 :            :  * 'mgr' to 'queue_id'.  If 'queue_id' is negative, then in-band control
    1828                 :            :  * flows will use the default queue. */
    1829                 :            : void
    1830                 :       4700 : connmgr_set_in_band_queue(struct connmgr *mgr, int queue_id)
    1831                 :            : {
    1832         [ -  + ]:       4700 :     if (queue_id != mgr->in_band_queue) {
    1833                 :          0 :         mgr->in_band_queue = queue_id;
    1834                 :          0 :         update_in_band_remotes(mgr);
    1835                 :            :     }
    1836                 :       4700 : }
    1837                 :            : 
    1838                 :            : static bool
    1839                 :       4700 : any_extras_changed(const struct connmgr *mgr,
    1840                 :            :                    const struct sockaddr_in *extras, size_t n)
    1841                 :            : {
    1842                 :            :     size_t i;
    1843                 :            : 
    1844         [ -  + ]:       4700 :     if (n != mgr->n_extra_remotes) {
    1845                 :          0 :         return true;
    1846                 :            :     }
    1847                 :            : 
    1848         [ -  + ]:       4700 :     for (i = 0; i < n; i++) {
    1849                 :          0 :         const struct sockaddr_in *old = &mgr->extra_in_band_remotes[i];
    1850                 :          0 :         const struct sockaddr_in *new = &extras[i];
    1851                 :            : 
    1852 [ #  # ][ #  # ]:          0 :         if (old->sin_addr.s_addr != new->sin_addr.s_addr ||
    1853                 :          0 :             old->sin_port != new->sin_port) {
    1854                 :          0 :             return true;
    1855                 :            :         }
    1856                 :            :     }
    1857                 :            : 
    1858                 :       4700 :     return false;
    1859                 :            : }
    1860                 :            : 
    1861                 :            : /* In-band implementation. */
    1862                 :            : 
    1863                 :            : bool
    1864                 :      23059 : connmgr_has_in_band(struct connmgr *mgr)
    1865                 :            : {
    1866                 :      23059 :     return mgr->in_band != NULL;
    1867                 :            : }
    1868                 :            : 
    1869                 :            : /* Fail-open and in-band implementation. */
    1870                 :            : 
    1871                 :            : /* Called by 'ofproto' after all flows have been flushed, to allow fail-open
    1872                 :            :  * and standalone mode to re-create their flows.
    1873                 :            :  *
    1874                 :            :  * In-band control has more sophisticated code that manages flows itself. */
    1875                 :            : void
    1876                 :        146 : connmgr_flushed(struct connmgr *mgr)
    1877                 :            :     OVS_EXCLUDED(ofproto_mutex)
    1878                 :            : {
    1879         [ -  + ]:        146 :     if (mgr->fail_open) {
    1880                 :          0 :         fail_open_flushed(mgr->fail_open);
    1881                 :            :     }
    1882                 :            : 
    1883                 :            :     /* If there are no controllers and we're in standalone mode, set up a flow
    1884                 :            :      * that matches every packet and directs them to OFPP_NORMAL (which goes to
    1885                 :            :      * us).  Otherwise, the switch is in secure mode and we won't pass any
    1886                 :            :      * traffic until a controller has been defined and it tells us to do so. */
    1887         [ +  + ]:        146 :     if (!connmgr_has_controllers(mgr)
    1888         [ +  - ]:        145 :         && mgr->fail_mode == OFPROTO_FAIL_STANDALONE) {
    1889                 :            :         struct ofpbuf ofpacts;
    1890                 :            :         struct match match;
    1891                 :            : 
    1892                 :        145 :         ofpbuf_init(&ofpacts, OFPACT_OUTPUT_SIZE);
    1893                 :        145 :         ofpact_put_OUTPUT(&ofpacts)->port = OFPP_NORMAL;
    1894                 :            : 
    1895                 :        145 :         match_init_catchall(&match);
    1896                 :        145 :         ofproto_add_flow(mgr->ofproto, &match, 0, ofpacts.data,
    1897                 :        145 :                                                   ofpacts.size);
    1898                 :            : 
    1899                 :        145 :         ofpbuf_uninit(&ofpacts);
    1900                 :            :     }
    1901                 :        146 : }
    1902                 :            : 
    1903                 :            : /* Returns the number of hidden rules created by the in-band and fail-open
    1904                 :            :  * implementations in table 0.  (Subtracting this count from the number of
    1905                 :            :  * rules in the table 0 classifier, as maintained in struct oftable, yields
    1906                 :            :  * the number of flows that OVS should report via OpenFlow for table 0.) */
    1907                 :            : int
    1908                 :         10 : connmgr_count_hidden_rules(const struct connmgr *mgr)
    1909                 :            : {
    1910                 :         10 :     int n_hidden = 0;
    1911         [ +  + ]:         10 :     if (mgr->in_band) {
    1912                 :          1 :         n_hidden += in_band_count_rules(mgr->in_band);
    1913                 :            :     }
    1914         [ -  + ]:         10 :     if (mgr->fail_open) {
    1915                 :          0 :         n_hidden += fail_open_count_rules(mgr->fail_open);
    1916                 :            :     }
    1917                 :         10 :     return n_hidden;
    1918                 :            : }
    1919                 :            : 
    1920                 :            : /* Creates a new ofservice for 'target' in 'mgr'.  Returns 0 if successful,
    1921                 :            :  * otherwise a positive errno value.
    1922                 :            :  *
    1923                 :            :  * ofservice_reconfigure() must be called to fully configure the new
    1924                 :            :  * ofservice. */
    1925                 :            : static int
    1926                 :        750 : ofservice_create(struct connmgr *mgr, const char *target,
    1927                 :            :                  uint32_t allowed_versions, uint8_t dscp)
    1928                 :            : {
    1929                 :            :     struct ofservice *ofservice;
    1930                 :            :     struct pvconn *pvconn;
    1931                 :            :     int error;
    1932                 :            : 
    1933                 :        750 :     error = pvconn_open(target, allowed_versions, dscp, &pvconn);
    1934         [ -  + ]:        750 :     if (error) {
    1935                 :          0 :         return error;
    1936                 :            :     }
    1937                 :            : 
    1938                 :        750 :     ofservice = xzalloc(sizeof *ofservice);
    1939                 :        750 :     hmap_insert(&mgr->services, &ofservice->node, hash_string(target, 0));
    1940                 :        750 :     ofservice->pvconn = pvconn;
    1941                 :        750 :     ofservice->allowed_versions = allowed_versions;
    1942                 :            : 
    1943                 :        750 :     return 0;
    1944                 :            : }
    1945                 :            : 
    1946                 :            : static void
    1947                 :        750 : ofservice_destroy(struct connmgr *mgr, struct ofservice *ofservice)
    1948                 :            : {
    1949                 :        750 :     hmap_remove(&mgr->services, &ofservice->node);
    1950                 :        750 :     pvconn_close(ofservice->pvconn);
    1951                 :        750 :     free(ofservice);
    1952                 :        750 : }
    1953                 :            : 
    1954                 :            : static void
    1955                 :       4701 : ofservice_reconfigure(struct ofservice *ofservice,
    1956                 :            :                       const struct ofproto_controller *c)
    1957                 :            : {
    1958                 :       4701 :     ofservice->probe_interval = c->probe_interval;
    1959                 :       4701 :     ofservice->rate_limit = c->rate_limit;
    1960                 :       4701 :     ofservice->burst_limit = c->burst_limit;
    1961                 :       4701 :     ofservice->enable_async_msgs = c->enable_async_msgs;
    1962                 :       4701 :     ofservice->dscp = c->dscp;
    1963                 :       4701 : }
    1964                 :            : 
    1965                 :            : /* Finds and returns the ofservice within 'mgr' that has the given
    1966                 :            :  * 'target', or a null pointer if none exists. */
    1967                 :            : static struct ofservice *
    1968                 :       4701 : ofservice_lookup(struct connmgr *mgr, const char *target)
    1969                 :            : {
    1970                 :            :     struct ofservice *ofservice;
    1971                 :            : 
    1972 [ +  + ][ -  + ]:       4701 :     HMAP_FOR_EACH_WITH_HASH (ofservice, node, hash_string(target, 0),
    1973                 :            :                              &mgr->services) {
    1974         [ +  - ]:       3951 :         if (!strcmp(pvconn_get_name(ofservice->pvconn), target)) {
    1975                 :       3951 :             return ofservice;
    1976                 :            :         }
    1977                 :            :     }
    1978                 :        750 :     return NULL;
    1979                 :            : }
    1980                 :            : 
    1981                 :            : /* Flow monitors (NXST_FLOW_MONITOR). */
    1982                 :            : 
    1983                 :            : /* A counter incremented when something significant happens to an OpenFlow
    1984                 :            :  * rule.
    1985                 :            :  *
    1986                 :            :  *     - When a rule is added, its 'add_seqno' and 'modify_seqno' are set to
    1987                 :            :  *       the current value (which is then incremented).
    1988                 :            :  *
    1989                 :            :  *     - When a rule is modified, its 'modify_seqno' is set to the current
    1990                 :            :  *       value (which is then incremented).
    1991                 :            :  *
    1992                 :            :  * Thus, by comparing an old value of monitor_seqno against a rule's
    1993                 :            :  * 'add_seqno', one can tell whether the rule was added before or after the old
    1994                 :            :  * value was read, and similarly for 'modify_seqno'.
    1995                 :            :  *
    1996                 :            :  * 32 bits should normally be sufficient (and would be nice, to save space in
    1997                 :            :  * each rule) but then we'd have to have some special cases for wraparound.
    1998                 :            :  *
    1999                 :            :  * We initialize monitor_seqno to 1 to allow 0 to be used as an invalid
    2000                 :            :  * value. */
    2001                 :            : static uint64_t monitor_seqno = 1;
    2002                 :            : 
    2003                 :      71674 : COVERAGE_DEFINE(ofmonitor_pause);
    2004                 :      71674 : COVERAGE_DEFINE(ofmonitor_resume);
    2005                 :            : 
    2006                 :            : enum ofperr
    2007                 :          4 : ofmonitor_create(const struct ofputil_flow_monitor_request *request,
    2008                 :            :                  struct ofconn *ofconn, struct ofmonitor **monitorp)
    2009                 :            :     OVS_REQUIRES(ofproto_mutex)
    2010                 :            : {
    2011                 :            :     struct ofmonitor *m;
    2012                 :            : 
    2013                 :          4 :     *monitorp = NULL;
    2014                 :            : 
    2015                 :          4 :     m = ofmonitor_lookup(ofconn, request->id);
    2016         [ -  + ]:          4 :     if (m) {
    2017                 :          0 :         return OFPERR_OFPMOFC_MONITOR_EXISTS;
    2018                 :            :     }
    2019                 :            : 
    2020                 :          4 :     m = xmalloc(sizeof *m);
    2021                 :          4 :     m->ofconn = ofconn;
    2022                 :          4 :     hmap_insert(&ofconn->monitors, &m->ofconn_node, hash_int(request->id, 0));
    2023                 :          4 :     m->id = request->id;
    2024                 :          4 :     m->flags = request->flags;
    2025                 :          4 :     m->out_port = request->out_port;
    2026                 :          4 :     m->table_id = request->table_id;
    2027                 :          4 :     minimatch_init(&m->match, &request->match);
    2028                 :            : 
    2029                 :          4 :     *monitorp = m;
    2030                 :          4 :     return 0;
    2031                 :            : }
    2032                 :            : 
    2033                 :            : struct ofmonitor *
    2034                 :          4 : ofmonitor_lookup(struct ofconn *ofconn, uint32_t id)
    2035                 :            :     OVS_REQUIRES(ofproto_mutex)
    2036                 :            : {
    2037                 :            :     struct ofmonitor *m;
    2038                 :            : 
    2039 [ -  + ][ -  + ]:          4 :     HMAP_FOR_EACH_IN_BUCKET (m, ofconn_node, hash_int(id, 0),
    2040                 :            :                              &ofconn->monitors) {
    2041         [ #  # ]:          0 :         if (m->id == id) {
    2042                 :          0 :             return m;
    2043                 :            :         }
    2044                 :            :     }
    2045                 :          4 :     return NULL;
    2046                 :            : }
    2047                 :            : 
    2048                 :            : void
    2049                 :          4 : ofmonitor_destroy(struct ofmonitor *m)
    2050                 :            :     OVS_REQUIRES(ofproto_mutex)
    2051                 :            : {
    2052         [ +  - ]:          4 :     if (m) {
    2053                 :          4 :         minimatch_destroy(&m->match);
    2054                 :          4 :         hmap_remove(&m->ofconn->monitors, &m->ofconn_node);
    2055                 :          4 :         free(m);
    2056                 :            :     }
    2057                 :          4 : }
    2058                 :            : 
    2059                 :            : void
    2060                 :      57573 : ofmonitor_report(struct connmgr *mgr, struct rule *rule,
    2061                 :            :                  enum nx_flow_update_event event,
    2062                 :            :                  enum ofp_flow_removed_reason reason,
    2063                 :            :                  const struct ofconn *abbrev_ofconn, ovs_be32 abbrev_xid,
    2064                 :            :                  const struct rule_actions *old_actions)
    2065                 :            :     OVS_REQUIRES(ofproto_mutex)
    2066                 :            : {
    2067                 :            :     enum nx_flow_monitor_flags update;
    2068                 :            :     struct ofconn *ofconn;
    2069                 :            : 
    2070         [ +  + ]:      57573 :     if (rule_is_hidden(rule)) {
    2071                 :         14 :         return;
    2072                 :            :     }
    2073                 :            : 
    2074   [ +  +  +  - ]:      57559 :     switch (event) {
    2075                 :            :     case NXFME_ADDED:
    2076                 :      31032 :         update = NXFMF_ADD;
    2077                 :      31032 :         rule->add_seqno = rule->modify_seqno = monitor_seqno++;
    2078                 :      31032 :         break;
    2079                 :            : 
    2080                 :            :     case NXFME_DELETED:
    2081                 :      26152 :         update = NXFMF_DELETE;
    2082                 :      26152 :         break;
    2083                 :            : 
    2084                 :            :     case NXFME_MODIFIED:
    2085                 :        375 :         update = NXFMF_MODIFY;
    2086                 :        375 :         rule->modify_seqno = monitor_seqno++;
    2087                 :        375 :         break;
    2088                 :            : 
    2089                 :            :     default:
    2090                 :            :     case NXFME_ABBREV:
    2091                 :          0 :         OVS_NOT_REACHED();
    2092                 :            :     }
    2093                 :            : 
    2094         [ +  + ]:     133525 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    2095                 :      75966 :         enum nx_flow_monitor_flags flags = 0;
    2096                 :            :         struct ofmonitor *m;
    2097                 :            : 
    2098         [ +  + ]:      75966 :         if (ofconn->monitor_paused) {
    2099                 :            :             /* Only send NXFME_DELETED notifications for flows that were added
    2100                 :            :              * before we paused. */
    2101         [ +  + ]:      11719 :             if (event != NXFME_DELETED
    2102         [ +  + ]:       7168 :                 || rule->add_seqno > ofconn->monitor_paused) {
    2103                 :       9100 :                 continue;
    2104                 :            :             }
    2105                 :            :         }
    2106                 :            : 
    2107 [ +  + ][ -  + ]:      72159 :         HMAP_FOR_EACH (m, ofconn_node, &ofconn->monitors) {
    2108         [ +  - ]:       5293 :             if (m->flags & update
    2109 [ -  + ][ #  # ]:       5293 :                 && (m->table_id == 0xff || m->table_id == rule->table_id)
    2110         [ +  + ]:       5293 :                 && (ofproto_rule_has_out_port(rule, m->out_port)
    2111         [ +  - ]:          2 :                     || (old_actions
    2112         [ +  + ]:          2 :                         && ofpacts_output_to_port(old_actions->ofpacts,
    2113                 :          2 :                                                   old_actions->ofpacts_len,
    2114                 :            :                                                   m->out_port)))
    2115         [ +  - ]:       5292 :                 && cls_rule_is_loose_match(&rule->cr, &m->match)) {
    2116                 :       5292 :                 flags |= m->flags;
    2117                 :            :             }
    2118                 :            :         }
    2119                 :            : 
    2120         [ +  + ]:      66866 :         if (flags) {
    2121         [ +  + ]:       5292 :             if (ovs_list_is_empty(&ofconn->updates)) {
    2122                 :       2655 :                 ofputil_start_flow_update(&ofconn->updates);
    2123                 :       2655 :                 ofconn->sent_abbrev_update = false;
    2124                 :            :             }
    2125                 :            : 
    2126 [ +  + ][ +  + ]:       5292 :             if (flags & NXFMF_OWN || ofconn != abbrev_ofconn
    2127         [ -  + ]:       5292 :                 || ofconn->monitor_paused) {
    2128                 :            :                 struct ofputil_flow_update fu;
    2129                 :            :                 struct match match;
    2130                 :            : 
    2131                 :       5289 :                 fu.event = event;
    2132         [ +  + ]:       5289 :                 fu.reason = event == NXFME_DELETED ? reason : 0;
    2133                 :       5289 :                 fu.table_id = rule->table_id;
    2134                 :       5289 :                 fu.cookie = rule->flow_cookie;
    2135                 :       5289 :                 minimatch_expand(&rule->cr.match, &match);
    2136                 :       5289 :                 fu.match = &match;
    2137                 :       5289 :                 fu.priority = rule->cr.priority;
    2138                 :            : 
    2139                 :       5289 :                 ovs_mutex_lock(&rule->mutex);
    2140                 :       5289 :                 fu.idle_timeout = rule->idle_timeout;
    2141                 :       5289 :                 fu.hard_timeout = rule->hard_timeout;
    2142                 :       5289 :                 ovs_mutex_unlock(&rule->mutex);
    2143                 :            : 
    2144         [ +  - ]:       5289 :                 if (flags & NXFMF_ACTIONS) {
    2145                 :       5289 :                     const struct rule_actions *actions = rule_get_actions(rule);
    2146                 :       5289 :                     fu.ofpacts = actions->ofpacts;
    2147                 :       5289 :                     fu.ofpacts_len = actions->ofpacts_len;
    2148                 :            :                 } else {
    2149                 :          0 :                     fu.ofpacts = NULL;
    2150                 :          0 :                     fu.ofpacts_len = 0;
    2151                 :            :                 }
    2152                 :       5289 :                 ofputil_append_flow_update(&fu, &ofconn->updates);
    2153         [ +  + ]:          3 :             } else if (!ofconn->sent_abbrev_update) {
    2154                 :            :                 struct ofputil_flow_update fu;
    2155                 :            : 
    2156                 :          1 :                 fu.event = NXFME_ABBREV;
    2157                 :          1 :                 fu.xid = abbrev_xid;
    2158                 :          1 :                 ofputil_append_flow_update(&fu, &ofconn->updates);
    2159                 :            : 
    2160                 :          1 :                 ofconn->sent_abbrev_update = true;
    2161                 :            :             }
    2162                 :            :         }
    2163                 :            :     }
    2164                 :            : }
    2165                 :            : 
    2166                 :            : void
    2167                 :      39931 : ofmonitor_flush(struct connmgr *mgr)
    2168                 :            :     OVS_REQUIRES(ofproto_mutex)
    2169                 :            : {
    2170                 :            :     struct ofconn *ofconn;
    2171                 :            : 
    2172         [ +  + ]:     101211 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    2173                 :            :         struct ofpbuf *msg;
    2174                 :            : 
    2175         [ +  + ]:      63936 :         LIST_FOR_EACH_POP (msg, list_node, &ofconn->updates) {
    2176                 :            :             unsigned int n_bytes;
    2177                 :            : 
    2178                 :       2656 :             ofconn_send(ofconn, msg, ofconn->monitor_counter);
    2179                 :       2656 :             n_bytes = rconn_packet_counter_n_bytes(ofconn->monitor_counter);
    2180 [ +  + ][ +  + ]:       2656 :             if (!ofconn->monitor_paused && n_bytes > 128 * 1024) {
    2181                 :            :                 struct ofpbuf *pause;
    2182                 :            : 
    2183                 :          1 :                 COVERAGE_INC(ofmonitor_pause);
    2184                 :          1 :                 ofconn->monitor_paused = monitor_seqno++;
    2185                 :          1 :                 pause = ofpraw_alloc_xid(OFPRAW_NXT_FLOW_MONITOR_PAUSED,
    2186                 :            :                                          OFP10_VERSION, htonl(0), 0);
    2187                 :          1 :                 ofconn_send(ofconn, pause, ofconn->monitor_counter);
    2188                 :            :             }
    2189                 :            :         }
    2190                 :            :     }
    2191                 :      39931 : }
    2192                 :            : 
    2193                 :            : static void
    2194                 :          1 : ofmonitor_resume(struct ofconn *ofconn)
    2195                 :            :     OVS_REQUIRES(ofproto_mutex)
    2196                 :            : {
    2197                 :            :     struct rule_collection rules;
    2198                 :            :     struct ofpbuf *resumed;
    2199                 :            :     struct ofmonitor *m;
    2200                 :            :     struct ovs_list msgs;
    2201                 :            : 
    2202                 :          1 :     rule_collection_init(&rules);
    2203 [ +  + ][ -  + ]:          2 :     HMAP_FOR_EACH (m, ofconn_node, &ofconn->monitors) {
    2204                 :          1 :         ofmonitor_collect_resume_rules(m, ofconn->monitor_paused, &rules);
    2205                 :            :     }
    2206                 :            : 
    2207                 :          1 :     ovs_list_init(&msgs);
    2208                 :          1 :     ofmonitor_compose_refresh_updates(&rules, &msgs);
    2209                 :            : 
    2210                 :          1 :     resumed = ofpraw_alloc_xid(OFPRAW_NXT_FLOW_MONITOR_RESUMED, OFP10_VERSION,
    2211                 :            :                                htonl(0), 0);
    2212                 :          1 :     ovs_list_push_back(&msgs, &resumed->list_node);
    2213                 :          1 :     ofconn_send_replies(ofconn, &msgs);
    2214                 :            : 
    2215                 :          1 :     ofconn->monitor_paused = 0;
    2216                 :          1 : }
    2217                 :            : 
    2218                 :            : static bool
    2219                 :     203892 : ofmonitor_may_resume(const struct ofconn *ofconn)
    2220                 :            :     OVS_REQUIRES(ofproto_mutex)
    2221                 :            : {
    2222                 :     203892 :     return (ofconn->monitor_paused != 0
    2223 [ +  + ][ +  + ]:     203892 :             && !rconn_packet_counter_n_packets(ofconn->monitor_counter));
    2224                 :            : }
    2225                 :            : 
    2226                 :            : static void
    2227                 :     157605 : ofmonitor_run(struct connmgr *mgr)
    2228                 :            : {
    2229                 :            :     struct ofconn *ofconn;
    2230                 :            : 
    2231                 :     157605 :     ovs_mutex_lock(&ofproto_mutex);
    2232         [ +  + ]:     258221 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    2233         [ +  + ]:     100616 :         if (ofmonitor_may_resume(ofconn)) {
    2234                 :          1 :             COVERAGE_INC(ofmonitor_resume);
    2235                 :          1 :             ofmonitor_resume(ofconn);
    2236                 :            :         }
    2237                 :            :     }
    2238                 :     157605 :     ovs_mutex_unlock(&ofproto_mutex);
    2239                 :     157605 : }
    2240                 :            : 
    2241                 :            : static void
    2242                 :     153645 : ofmonitor_wait(struct connmgr *mgr)
    2243                 :            : {
    2244                 :            :     struct ofconn *ofconn;
    2245                 :            : 
    2246                 :     153645 :     ovs_mutex_lock(&ofproto_mutex);
    2247         [ +  + ]:     256921 :     LIST_FOR_EACH (ofconn, node, &mgr->all_conns) {
    2248         [ -  + ]:     103276 :         if (ofmonitor_may_resume(ofconn)) {
    2249                 :          0 :             poll_immediate_wake();
    2250                 :            :         }
    2251                 :            :     }
    2252                 :     153645 :     ovs_mutex_unlock(&ofproto_mutex);
    2253                 :     153645 : }
    2254                 :            : 
    2255                 :            : void
    2256                 :       1051 : ofproto_async_msg_free(struct ofproto_async_msg *am)
    2257                 :            : {
    2258                 :       1051 :     free(am->pin.up.public.packet);
    2259                 :       1051 :     free(am->pin.up.public.userdata);
    2260                 :       1051 :     free(am->pin.up.stack);
    2261                 :       1051 :     free(am->pin.up.actions);
    2262                 :       1051 :     free(am->pin.up.action_set);
    2263                 :       1051 :     free(am);
    2264                 :       1051 : }

Generated by: LCOV version 1.12