LCOV - code coverage report
Current view: top level - ofproto - ofproto-dpif.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 2192 2496 87.8 %
Date: 2016-09-14 01:02:56 Functions: 233 254 91.7 %
Branches: 969 1342 72.2 %

           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                 :            : 
      20                 :            : #include "bfd.h"
      21                 :            : #include "bond.h"
      22                 :            : #include "bundle.h"
      23                 :            : #include "byte-order.h"
      24                 :            : #include "connectivity.h"
      25                 :            : #include "connmgr.h"
      26                 :            : #include "coverage.h"
      27                 :            : #include "cfm.h"
      28                 :            : #include "dpif.h"
      29                 :            : #include "fail-open.h"
      30                 :            : #include "guarded-list.h"
      31                 :            : #include "hmapx.h"
      32                 :            : #include "lacp.h"
      33                 :            : #include "learn.h"
      34                 :            : #include "mac-learning.h"
      35                 :            : #include "mcast-snooping.h"
      36                 :            : #include "multipath.h"
      37                 :            : #include "netdev-vport.h"
      38                 :            : #include "netdev.h"
      39                 :            : #include "netlink.h"
      40                 :            : #include "nx-match.h"
      41                 :            : #include "odp-util.h"
      42                 :            : #include "odp-execute.h"
      43                 :            : #include "ofproto/ofproto-dpif.h"
      44                 :            : #include "ofproto/ofproto-provider.h"
      45                 :            : #include "ofproto-dpif-ipfix.h"
      46                 :            : #include "ofproto-dpif-mirror.h"
      47                 :            : #include "ofproto-dpif-monitor.h"
      48                 :            : #include "ofproto-dpif-rid.h"
      49                 :            : #include "ofproto-dpif-sflow.h"
      50                 :            : #include "ofproto-dpif-upcall.h"
      51                 :            : #include "ofproto-dpif-xlate.h"
      52                 :            : #include "openvswitch/ofp-actions.h"
      53                 :            : #include "openvswitch/dynamic-string.h"
      54                 :            : #include "openvswitch/meta-flow.h"
      55                 :            : #include "openvswitch/ofp-parse.h"
      56                 :            : #include "openvswitch/ofp-print.h"
      57                 :            : #include "openvswitch/ofp-util.h"
      58                 :            : #include "openvswitch/ofpbuf.h"
      59                 :            : #include "openvswitch/vlog.h"
      60                 :            : #include "ovs-lldp.h"
      61                 :            : #include "ovs-rcu.h"
      62                 :            : #include "ovs-router.h"
      63                 :            : #include "poll-loop.h"
      64                 :            : #include "seq.h"
      65                 :            : #include "simap.h"
      66                 :            : #include "smap.h"
      67                 :            : #include "timer.h"
      68                 :            : #include "tunnel.h"
      69                 :            : #include "unaligned.h"
      70                 :            : #include "unixctl.h"
      71                 :            : #include "util.h"
      72                 :            : #include "vlan-bitmap.h"
      73                 :            : 
      74                 :       1288 : VLOG_DEFINE_THIS_MODULE(ofproto_dpif);
      75                 :            : 
      76                 :      71698 : COVERAGE_DEFINE(ofproto_dpif_expired);
      77                 :      71668 : COVERAGE_DEFINE(packet_in_overflow);
      78                 :            : 
      79                 :            : struct flow_miss;
      80                 :            : 
      81                 :            : struct rule_dpif {
      82                 :            :     struct rule up;
      83                 :            : 
      84                 :            :     /* These statistics:
      85                 :            :      *
      86                 :            :      *   - Do include packets and bytes from datapath flows which have not
      87                 :            :      *   recently been processed by a revalidator. */
      88                 :            :     struct ovs_mutex stats_mutex;
      89                 :            :     struct dpif_flow_stats stats OVS_GUARDED;
      90                 :            : 
      91                 :            :    /* In non-NULL, will point to a new rule (for which a reference is held) to
      92                 :            :     * which all the stats updates should be forwarded. This exists only
      93                 :            :     * transitionally when flows are replaced.
      94                 :            :     *
      95                 :            :     * Protected by stats_mutex.  If both 'rule->stats_mutex' and
      96                 :            :     * 'rule->new_rule->stats_mutex' must be held together, acquire them in that
      97                 :            :     * order, */
      98                 :            :     struct rule_dpif *new_rule OVS_GUARDED;
      99                 :            :     bool forward_counts OVS_GUARDED;   /* Forward counts? 'used' time will be
     100                 :            :                                         * forwarded in all cases. */
     101                 :            : 
     102                 :            :     /* If non-zero then the recirculation id that has
     103                 :            :      * been allocated for use with this rule.
     104                 :            :      * The recirculation id and associated internal flow should
     105                 :            :      * be freed when the rule is freed */
     106                 :            :     uint32_t recirc_id;
     107                 :            : };
     108                 :            : 
     109                 :            : /* RULE_CAST() depends on this. */
     110                 :            : BUILD_ASSERT_DECL(offsetof(struct rule_dpif, up) == 0);
     111                 :            : 
     112                 :            : static void rule_get_stats(struct rule *, uint64_t *packets, uint64_t *bytes,
     113                 :            :                            long long int *used);
     114                 :            : static struct rule_dpif *rule_dpif_cast(const struct rule *);
     115                 :            : static void rule_expire(struct rule_dpif *, long long now);
     116                 :            : 
     117                 :            : struct group_dpif {
     118                 :            :     struct ofgroup up;
     119                 :            : 
     120                 :            :     /* These statistics:
     121                 :            :      *
     122                 :            :      *   - Do include packets and bytes from datapath flows which have not
     123                 :            :      *   recently been processed by a revalidator. */
     124                 :            :     struct ovs_mutex stats_mutex;
     125                 :            :     uint64_t packet_count OVS_GUARDED;  /* Number of packets received. */
     126                 :            :     uint64_t byte_count OVS_GUARDED;    /* Number of bytes received. */
     127                 :            : };
     128                 :            : 
     129                 :            : struct ofbundle {
     130                 :            :     struct hmap_node hmap_node; /* In struct ofproto's "bundles" hmap. */
     131                 :            :     struct ofproto_dpif *ofproto; /* Owning ofproto. */
     132                 :            :     void *aux;                  /* Key supplied by ofproto's client. */
     133                 :            :     char *name;                 /* Identifier for log messages. */
     134                 :            : 
     135                 :            :     /* Configuration. */
     136                 :            :     struct ovs_list ports;      /* Contains "struct ofport"s. */
     137                 :            :     enum port_vlan_mode vlan_mode; /* VLAN mode */
     138                 :            :     int vlan;                   /* -1=trunk port, else a 12-bit VLAN ID. */
     139                 :            :     unsigned long *trunks;      /* Bitmap of trunked VLANs, if 'vlan' == -1.
     140                 :            :                                  * NULL if all VLANs are trunked. */
     141                 :            :     struct lacp *lacp;          /* LACP if LACP is enabled, otherwise NULL. */
     142                 :            :     struct bond *bond;          /* Nonnull iff more than one port. */
     143                 :            :     bool use_priority_tags;     /* Use 802.1p tag for frames in VLAN 0? */
     144                 :            : 
     145                 :            :     /* Status. */
     146                 :            :     bool floodable;          /* True if no port has OFPUTIL_PC_NO_FLOOD set. */
     147                 :            : };
     148                 :            : 
     149                 :            : static void bundle_remove(struct ofport *);
     150                 :            : static void bundle_update(struct ofbundle *);
     151                 :            : static void bundle_destroy(struct ofbundle *);
     152                 :            : static void bundle_del_port(struct ofport_dpif *);
     153                 :            : static void bundle_run(struct ofbundle *);
     154                 :            : static void bundle_wait(struct ofbundle *);
     155                 :            : static void bundle_flush_macs(struct ofbundle *, bool);
     156                 :            : static void bundle_move(struct ofbundle *, struct ofbundle *);
     157                 :            : 
     158                 :            : static void stp_run(struct ofproto_dpif *ofproto);
     159                 :            : static void stp_wait(struct ofproto_dpif *ofproto);
     160                 :            : static int set_stp_port(struct ofport *,
     161                 :            :                         const struct ofproto_port_stp_settings *);
     162                 :            : 
     163                 :            : static void rstp_run(struct ofproto_dpif *ofproto);
     164                 :            : static void set_rstp_port(struct ofport *,
     165                 :            :                          const struct ofproto_port_rstp_settings *);
     166                 :            : 
     167                 :            : struct ofport_dpif {
     168                 :            :     struct hmap_node odp_port_node; /* In dpif_backer's "odp_to_ofport_map". */
     169                 :            :     struct ofport up;
     170                 :            : 
     171                 :            :     odp_port_t odp_port;
     172                 :            :     struct ofbundle *bundle;    /* Bundle that contains this port, if any. */
     173                 :            :     struct ovs_list bundle_node;/* In struct ofbundle's "ports" list. */
     174                 :            :     struct cfm *cfm;            /* Connectivity Fault Management, if any. */
     175                 :            :     struct bfd *bfd;            /* BFD, if any. */
     176                 :            :     struct lldp *lldp;          /* lldp, if any. */
     177                 :            :     bool may_enable;            /* May be enabled in bonds. */
     178                 :            :     bool is_tunnel;             /* This port is a tunnel. */
     179                 :            :     bool is_layer3;             /* This is a layer 3 port. */
     180                 :            :     long long int carrier_seq;  /* Carrier status changes. */
     181                 :            :     struct ofport_dpif *peer;   /* Peer if patch port. */
     182                 :            : 
     183                 :            :     /* Spanning tree. */
     184                 :            :     struct stp_port *stp_port;  /* Spanning Tree Protocol, if any. */
     185                 :            :     enum stp_state stp_state;   /* Always STP_DISABLED if STP not in use. */
     186                 :            :     long long int stp_state_entered;
     187                 :            : 
     188                 :            :     /* Rapid Spanning Tree. */
     189                 :            :     struct rstp_port *rstp_port; /* Rapid Spanning Tree Protocol, if any. */
     190                 :            :     enum rstp_state rstp_state; /* Always RSTP_DISABLED if RSTP not in use. */
     191                 :            : 
     192                 :            :     /* Queue to DSCP mapping. */
     193                 :            :     struct ofproto_port_queue *qdscp;
     194                 :            :     size_t n_qdscp;
     195                 :            : };
     196                 :            : 
     197                 :            : static odp_port_t ofp_port_to_odp_port(const struct ofproto_dpif *,
     198                 :            :                                        ofp_port_t);
     199                 :            : 
     200                 :            : static ofp_port_t odp_port_to_ofp_port(const struct ofproto_dpif *,
     201                 :            :                                        odp_port_t);
     202                 :            : 
     203                 :            : static struct ofport_dpif *
     204                 :     563780 : ofport_dpif_cast(const struct ofport *ofport)
     205                 :            : {
     206         [ +  - ]:     563780 :     return ofport ? CONTAINER_OF(ofport, struct ofport_dpif, up) : NULL;
     207                 :            : }
     208                 :            : 
     209                 :            : static void port_run(struct ofport_dpif *);
     210                 :            : static int set_bfd(struct ofport *, const struct smap *);
     211                 :            : static int set_cfm(struct ofport *, const struct cfm_settings *);
     212                 :            : static int set_lldp(struct ofport *ofport_, const struct smap *cfg);
     213                 :            : static void ofport_update_peer(struct ofport_dpif *);
     214                 :            : 
     215                 :            : /* Reasons that we might need to revalidate every datapath flow, and
     216                 :            :  * corresponding coverage counters.
     217                 :            :  *
     218                 :            :  * A value of 0 means that there is no need to revalidate.
     219                 :            :  *
     220                 :            :  * It would be nice to have some cleaner way to integrate with coverage
     221                 :            :  * counters, but with only a few reasons I guess this is good enough for
     222                 :            :  * now. */
     223                 :            : enum revalidate_reason {
     224                 :            :     REV_RECONFIGURE = 1,       /* Switch configuration changed. */
     225                 :            :     REV_STP,                   /* Spanning tree protocol port status change. */
     226                 :            :     REV_RSTP,                  /* RSTP port status change. */
     227                 :            :     REV_BOND,                  /* Bonding changed. */
     228                 :            :     REV_PORT_TOGGLED,          /* Port enabled or disabled by CFM, LACP, ...*/
     229                 :            :     REV_FLOW_TABLE,            /* Flow table changed. */
     230                 :            :     REV_MAC_LEARNING,          /* Mac learning changed. */
     231                 :            :     REV_MCAST_SNOOPING,        /* Multicast snooping changed. */
     232                 :            : };
     233                 :      97552 : COVERAGE_DEFINE(rev_reconfigure);
     234                 :      71686 : COVERAGE_DEFINE(rev_stp);
     235                 :      71686 : COVERAGE_DEFINE(rev_rstp);
     236                 :      71860 : COVERAGE_DEFINE(rev_bond);
     237                 :      74356 : COVERAGE_DEFINE(rev_port_toggled);
     238                 :     149098 : COVERAGE_DEFINE(rev_flow_table);
     239                 :      74902 : COVERAGE_DEFINE(rev_mac_learning);
     240                 :      71668 : COVERAGE_DEFINE(rev_mcast_snooping);
     241                 :            : 
     242                 :            : /* All datapaths of a given type share a single dpif backer instance. */
     243                 :            : struct dpif_backer {
     244                 :            :     char *type;
     245                 :            :     int refcount;
     246                 :            :     struct dpif *dpif;
     247                 :            :     struct udpif *udpif;
     248                 :            : 
     249                 :            :     struct ovs_rwlock odp_to_ofport_lock;
     250                 :            :     struct hmap odp_to_ofport_map OVS_GUARDED; /* Contains "struct ofport"s. */
     251                 :            : 
     252                 :            :     struct simap tnl_backers;      /* Set of dpif ports backing tunnels. */
     253                 :            : 
     254                 :            :     enum revalidate_reason need_revalidate; /* Revalidate all flows. */
     255                 :            : 
     256                 :            :     bool recv_set_enable; /* Enables or disables receiving packets. */
     257                 :            : 
     258                 :            :     /* Version string of the datapath stored in OVSDB. */
     259                 :            :     char *dp_version_string;
     260                 :            : 
     261                 :            :     /* Datapath feature support. */
     262                 :            :     struct dpif_backer_support support;
     263                 :            :     struct atomic_count tnl_count;
     264                 :            : };
     265                 :            : 
     266                 :            : /* All existing ofproto_backer instances, indexed by ofproto->up.type. */
     267                 :            : static struct shash all_dpif_backers = SHASH_INITIALIZER(&all_dpif_backers);
     268                 :            : 
     269                 :            : struct ofproto_dpif {
     270                 :            :     struct hmap_node all_ofproto_dpifs_node; /* In 'all_ofproto_dpifs'. */
     271                 :            :     struct ofproto up;
     272                 :            :     struct dpif_backer *backer;
     273                 :            : 
     274                 :            :     /* Unique identifier for this instantiation of this bridge in this running
     275                 :            :      * process.  */
     276                 :            :     struct uuid uuid;
     277                 :            : 
     278                 :            :     ATOMIC(ovs_version_t) tables_version;  /* For classifier lookups. */
     279                 :            : 
     280                 :            :     uint64_t dump_seq; /* Last read of udpif_dump_seq(). */
     281                 :            : 
     282                 :            :     /* Special OpenFlow rules. */
     283                 :            :     struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */
     284                 :            :     struct rule_dpif *no_packet_in_rule; /* Drops flow table misses. */
     285                 :            :     struct rule_dpif *drop_frags_rule; /* Used in OFPUTIL_FRAG_DROP mode. */
     286                 :            : 
     287                 :            :     /* Bridging. */
     288                 :            :     struct netflow *netflow;
     289                 :            :     struct dpif_sflow *sflow;
     290                 :            :     struct dpif_ipfix *ipfix;
     291                 :            :     struct hmap bundles;        /* Contains "struct ofbundle"s. */
     292                 :            :     struct mac_learning *ml;
     293                 :            :     struct mcast_snooping *ms;
     294                 :            :     bool has_bonded_bundles;
     295                 :            :     bool lacp_enabled;
     296                 :            :     struct mbridge *mbridge;
     297                 :            : 
     298                 :            :     struct ovs_mutex stats_mutex;
     299                 :            :     struct netdev_stats stats OVS_GUARDED; /* To account packets generated and
     300                 :            :                                             * consumed in userspace. */
     301                 :            : 
     302                 :            :     /* Spanning tree. */
     303                 :            :     struct stp *stp;
     304                 :            :     long long int stp_last_tick;
     305                 :            : 
     306                 :            :     /* Rapid Spanning Tree. */
     307                 :            :     struct rstp *rstp;
     308                 :            :     long long int rstp_last_tick;
     309                 :            : 
     310                 :            :     /* Ports. */
     311                 :            :     struct sset ports;             /* Set of standard port names. */
     312                 :            :     struct sset ghost_ports;       /* Ports with no datapath port. */
     313                 :            :     struct sset port_poll_set;     /* Queued names for port_poll() reply. */
     314                 :            :     int port_poll_errno;           /* Last errno for port_poll() reply. */
     315                 :            :     uint64_t change_seq;           /* Connectivity status changes. */
     316                 :            : 
     317                 :            :     /* Work queues. */
     318                 :            :     struct guarded_list ams;      /* Contains "struct ofproto_async_msgs"s. */
     319                 :            :     struct seq *ams_seq;          /* For notifying 'ams' reception. */
     320                 :            :     uint64_t ams_seqno;
     321                 :            : };
     322                 :            : 
     323                 :            : /* All existing ofproto_dpif instances, indexed by ->up.name. */
     324                 :            : static struct hmap all_ofproto_dpifs = HMAP_INITIALIZER(&all_ofproto_dpifs);
     325                 :            : 
     326                 :            : static bool ofproto_use_tnl_push_pop = true;
     327                 :            : static void ofproto_unixctl_init(void);
     328                 :            : 
     329                 :            : static inline struct ofproto_dpif *
     330                 :    1204441 : ofproto_dpif_cast(const struct ofproto *ofproto)
     331                 :            : {
     332         [ -  + ]:    1204441 :     ovs_assert(ofproto->ofproto_class == &ofproto_dpif_class);
     333                 :    1204441 :     return CONTAINER_OF(ofproto, struct ofproto_dpif, up);
     334                 :            : }
     335                 :            : 
     336                 :            : bool
     337                 :      37059 : ofproto_dpif_get_enable_ufid(const struct dpif_backer *backer)
     338                 :            : {
     339                 :      37059 :     return backer->support.ufid;
     340                 :            : }
     341                 :            : 
     342                 :            : struct dpif_backer_support *
     343                 :      41074 : ofproto_dpif_get_support(const struct ofproto_dpif *ofproto)
     344                 :            : {
     345                 :      41074 :     return &ofproto->backer->support;
     346                 :            : }
     347                 :            : 
     348                 :            : static void ofproto_trace(struct ofproto_dpif *, struct flow *,
     349                 :            :                           const struct dp_packet *packet,
     350                 :            :                           const struct ofpact[], size_t ofpacts_len,
     351                 :            :                           struct ds *);
     352                 :            : 
     353                 :            : /* Global variables. */
     354                 :            : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
     355                 :            : 
     356                 :            : /* Initial mappings of port to bridge mappings. */
     357                 :            : static struct shash init_ofp_ports = SHASH_INITIALIZER(&init_ofp_ports);
     358                 :            : 
     359                 :            : /* Executes 'fm'.  The caller retains ownership of 'fm' and everything in
     360                 :            :  * it. */
     361                 :            : void
     362                 :         51 : ofproto_dpif_flow_mod(struct ofproto_dpif *ofproto,
     363                 :            :                       const struct ofputil_flow_mod *fm)
     364                 :            : {
     365                 :         51 :     ofproto_flow_mod(&ofproto->up, fm);
     366                 :         51 : }
     367                 :            : 
     368                 :            : /* Appends 'am' to the queue of asynchronous messages to be sent to the
     369                 :            :  * controller.  Takes ownership of 'am' and any data it points to. */
     370                 :            : void
     371                 :       1051 : ofproto_dpif_send_async_msg(struct ofproto_dpif *ofproto,
     372                 :            :                             struct ofproto_async_msg *am)
     373                 :            : {
     374         [ -  + ]:       1051 :     if (!guarded_list_push_back(&ofproto->ams, &am->list_node, 1024)) {
     375                 :          0 :         COVERAGE_INC(packet_in_overflow);
     376                 :          0 :         ofproto_async_msg_free(am);
     377                 :            :     }
     378                 :            : 
     379                 :            :     /* Wakes up main thread for packet-in I/O. */
     380                 :       1051 :     seq_change(ofproto->ams_seq);
     381                 :       1051 : }
     382                 :            : 
     383                 :            : /* The default "table-miss" behaviour for OpenFlow1.3+ is to drop the
     384                 :            :  * packet rather than to send the packet to the controller.
     385                 :            :  *
     386                 :            :  * This function returns false to indicate that a packet_in message
     387                 :            :  * for a "table-miss" should be sent to at least one controller.
     388                 :            :  * False otherwise. */
     389                 :            : bool
     390                 :          0 : ofproto_dpif_wants_packet_in_on_miss(struct ofproto_dpif *ofproto)
     391                 :            : {
     392                 :          0 :     return connmgr_wants_packet_in_on_miss(ofproto->up.connmgr);
     393                 :            : }
     394                 :            : 
     395                 :            : /* Factory functions. */
     396                 :            : 
     397                 :            : static void
     398                 :        615 : init(const struct shash *iface_hints)
     399                 :            : {
     400                 :            :     struct shash_node *node;
     401                 :            : 
     402                 :            :     /* Make a local copy, since we don't own 'iface_hints' elements. */
     403 [ +  + ][ -  + ]:        624 :     SHASH_FOR_EACH(node, iface_hints) {
     404                 :          9 :         const struct iface_hint *orig_hint = node->data;
     405                 :          9 :         struct iface_hint *new_hint = xmalloc(sizeof *new_hint);
     406                 :            : 
     407                 :          9 :         new_hint->br_name = xstrdup(orig_hint->br_name);
     408                 :          9 :         new_hint->br_type = xstrdup(orig_hint->br_type);
     409                 :          9 :         new_hint->ofp_port = orig_hint->ofp_port;
     410                 :            : 
     411                 :          9 :         shash_add(&init_ofp_ports, node->name, new_hint);
     412                 :            :     }
     413                 :            : 
     414                 :        615 :     ofproto_unixctl_init();
     415                 :        615 :     udpif_init();
     416                 :        615 : }
     417                 :            : 
     418                 :            : static void
     419                 :     773926 : enumerate_types(struct sset *types)
     420                 :            : {
     421                 :     773926 :     dp_enumerate_types(types);
     422                 :     773926 : }
     423                 :            : 
     424                 :            : static int
     425                 :       8408 : enumerate_names(const char *type, struct sset *names)
     426                 :            : {
     427                 :            :     struct ofproto_dpif *ofproto;
     428                 :            : 
     429                 :       8408 :     sset_clear(names);
     430 [ +  + ][ -  + ]:      16634 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     431         [ +  + ]:       8226 :         if (strcmp(type, ofproto->up.type)) {
     432                 :       4275 :             continue;
     433                 :            :         }
     434                 :       3951 :         sset_add(names, ofproto->up.name);
     435                 :            :     }
     436                 :            : 
     437                 :       8408 :     return 0;
     438                 :            : }
     439                 :            : 
     440                 :            : static int
     441                 :          0 : del(const char *type, const char *name)
     442                 :            : {
     443                 :            :     struct dpif *dpif;
     444                 :            :     int error;
     445                 :            : 
     446                 :          0 :     error = dpif_open(name, type, &dpif);
     447         [ #  # ]:          0 :     if (!error) {
     448                 :          0 :         error = dpif_delete(dpif);
     449                 :          0 :         dpif_close(dpif);
     450                 :            :     }
     451                 :          0 :     return error;
     452                 :            : }
     453                 :            : 
     454                 :            : static const char *
     455                 :      64923 : port_open_type(const char *datapath_type, const char *port_type)
     456                 :            : {
     457                 :      64923 :     return dpif_port_open_type(datapath_type, port_type);
     458                 :            : }
     459                 :            : 
     460                 :            : /* Type functions. */
     461                 :            : 
     462                 :            : static void process_dpif_port_changes(struct dpif_backer *);
     463                 :            : static void process_dpif_all_ports_changed(struct dpif_backer *);
     464                 :            : static void process_dpif_port_change(struct dpif_backer *,
     465                 :            :                                      const char *devname);
     466                 :            : static void process_dpif_port_error(struct dpif_backer *, int error);
     467                 :            : 
     468                 :            : static struct ofproto_dpif *
     469                 :       5042 : lookup_ofproto_dpif_by_port_name(const char *name)
     470                 :            : {
     471                 :            :     struct ofproto_dpif *ofproto;
     472                 :            : 
     473 [ +  + ][ -  + ]:       8482 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     474         [ +  + ]:       7290 :         if (sset_contains(&ofproto->ports, name)) {
     475                 :       3850 :             return ofproto;
     476                 :            :         }
     477                 :            :     }
     478                 :            : 
     479                 :       1192 :     return NULL;
     480                 :            : }
     481                 :            : 
     482                 :            : bool
     483                 :         90 : ofproto_dpif_backer_enabled(struct dpif_backer* backer)
     484                 :            : {
     485                 :         90 :     return backer->recv_set_enable;
     486                 :            : }
     487                 :            : 
     488                 :            : static int
     489                 :     245845 : type_run(const char *type)
     490                 :            : {
     491                 :            :     struct dpif_backer *backer;
     492                 :            : 
     493                 :     245845 :     backer = shash_find_data(&all_dpif_backers, type);
     494         [ +  + ]:     245845 :     if (!backer) {
     495                 :            :         /* This is not necessarily a problem, since backers are only
     496                 :            :          * created on demand. */
     497                 :     140146 :         return 0;
     498                 :            :     }
     499                 :            : 
     500                 :            :     /* This must be called before dpif_run() */
     501                 :     105699 :     dpif_poll_threads_set(backer->dpif, pmd_cpu_mask);
     502                 :            : 
     503         [ +  + ]:     105699 :     if (dpif_run(backer->dpif)) {
     504                 :        715 :         backer->need_revalidate = REV_RECONFIGURE;
     505                 :            :     }
     506                 :            : 
     507                 :     105699 :     udpif_run(backer->udpif);
     508                 :            : 
     509                 :            :     /* If vswitchd started with other_config:flow_restore_wait set as "true",
     510                 :            :      * and the configuration has now changed to "false", enable receiving
     511                 :            :      * packets from the datapath. */
     512 [ +  + ][ +  + ]:     105699 :     if (!backer->recv_set_enable && !ofproto_get_flow_restore_wait()) {
     513                 :            :         int error;
     514                 :            : 
     515                 :          1 :         backer->recv_set_enable = true;
     516                 :            : 
     517                 :          1 :         error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
     518         [ -  + ]:          1 :         if (error) {
     519         [ #  # ]:          0 :             VLOG_ERR("Failed to enable receiving packets in dpif.");
     520                 :          0 :             return error;
     521                 :            :         }
     522                 :          1 :         dpif_flow_flush(backer->dpif);
     523                 :          1 :         backer->need_revalidate = REV_RECONFIGURE;
     524                 :            :     }
     525                 :            : 
     526         [ +  + ]:     105699 :     if (backer->recv_set_enable) {
     527                 :     105660 :         udpif_set_threads(backer->udpif, n_handlers, n_revalidators);
     528                 :            :     }
     529                 :            : 
     530         [ +  + ]:     105699 :     if (backer->need_revalidate) {
     531                 :            :         struct ofproto_dpif *ofproto;
     532                 :            :         struct simap_node *node;
     533                 :            :         struct simap tmp_backers;
     534                 :            : 
     535                 :            :         /* Handle tunnel garbage collection. */
     536                 :      18244 :         simap_init(&tmp_backers);
     537                 :      18244 :         simap_swap(&backer->tnl_backers, &tmp_backers);
     538                 :            : 
     539 [ +  + ][ -  + ]:      41303 :         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     540                 :            :             struct ofport_dpif *iter;
     541                 :            : 
     542         [ -  + ]:      23059 :             if (backer != ofproto->backer) {
     543                 :          0 :                 continue;
     544                 :            :             }
     545                 :            : 
     546 [ +  + ][ -  + ]:     123368 :             HMAP_FOR_EACH (iter, up.hmap_node, &ofproto->up.ports) {
     547                 :            :                 char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
     548                 :            :                 const char *dp_port;
     549                 :            : 
     550         [ +  + ]:     100309 :                 if (!iter->is_tunnel) {
     551                 :      76324 :                     continue;
     552                 :            :                 }
     553                 :            : 
     554                 :      23985 :                 dp_port = netdev_vport_get_dpif_port(iter->up.netdev,
     555                 :            :                                                      namebuf, sizeof namebuf);
     556                 :      23985 :                 node = simap_find(&tmp_backers, dp_port);
     557         [ +  + ]:      23985 :                 if (node) {
     558                 :       2741 :                     simap_put(&backer->tnl_backers, dp_port, node->data);
     559                 :       2741 :                     simap_delete(&tmp_backers, node);
     560                 :       2741 :                     node = simap_find(&backer->tnl_backers, dp_port);
     561                 :            :                 } else {
     562                 :      21244 :                     node = simap_find(&backer->tnl_backers, dp_port);
     563         [ +  + ]:      21244 :                     if (!node) {
     564                 :          2 :                         odp_port_t odp_port = ODPP_NONE;
     565                 :            : 
     566         [ +  - ]:          2 :                         if (!dpif_port_add(backer->dpif, iter->up.netdev,
     567                 :            :                                            &odp_port)) {
     568                 :          2 :                             simap_put(&backer->tnl_backers, dp_port,
     569                 :            :                                       odp_to_u32(odp_port));
     570                 :          2 :                             node = simap_find(&backer->tnl_backers, dp_port);
     571                 :            :                         }
     572                 :            :                     }
     573                 :            :                 }
     574                 :            : 
     575         [ +  - ]:      23985 :                 iter->odp_port = node ? u32_to_odp(node->data) : ODPP_NONE;
     576         [ +  + ]:      23985 :                 if (tnl_port_reconfigure(iter, iter->up.netdev,
     577                 :            :                                          iter->odp_port,
     578                 :      23985 :                                          ovs_native_tunneling_is_on(ofproto), dp_port)) {
     579                 :      23985 :                     backer->need_revalidate = REV_RECONFIGURE;
     580                 :            :                 }
     581                 :            :             }
     582                 :            :         }
     583                 :            : 
     584 [ +  + ][ -  + ]:      18277 :         SIMAP_FOR_EACH (node, &tmp_backers) {
     585                 :         33 :             dpif_port_del(backer->dpif, u32_to_odp(node->data));
     586                 :            :         }
     587                 :      18244 :         simap_destroy(&tmp_backers);
     588                 :            : 
     589   [ +  +  +  +  :      18244 :         switch (backer->need_revalidate) {
             +  +  +  -  
                      - ]
     590                 :       4314 :         case REV_RECONFIGURE:    COVERAGE_INC(rev_reconfigure);    break;
     591                 :          3 :         case REV_STP:            COVERAGE_INC(rev_stp);            break;
     592                 :          3 :         case REV_RSTP:           COVERAGE_INC(rev_rstp);           break;
     593                 :         32 :         case REV_BOND:           COVERAGE_INC(rev_bond);           break;
     594                 :        448 :         case REV_PORT_TOGGLED:   COVERAGE_INC(rev_port_toggled);   break;
     595                 :      12905 :         case REV_FLOW_TABLE:     COVERAGE_INC(rev_flow_table);     break;
     596                 :        539 :         case REV_MAC_LEARNING:   COVERAGE_INC(rev_mac_learning);   break;
     597                 :          0 :         case REV_MCAST_SNOOPING: COVERAGE_INC(rev_mcast_snooping); break;
     598                 :            :         }
     599                 :      18244 :         backer->need_revalidate = 0;
     600                 :            : 
     601 [ +  + ][ -  + ]:      41303 :         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     602                 :            :             struct ofport_dpif *ofport;
     603                 :            :             struct ofbundle *bundle;
     604                 :            : 
     605         [ -  + ]:      23059 :             if (ofproto->backer != backer) {
     606                 :          0 :                 continue;
     607                 :            :             }
     608                 :            : 
     609                 :      23059 :             xlate_txn_start();
     610                 :      23059 :             xlate_ofproto_set(ofproto, ofproto->up.name,
     611                 :      23059 :                               ofproto->backer->dpif, ofproto->ml,
     612                 :      23059 :                               ofproto->stp, ofproto->rstp, ofproto->ms,
     613                 :      23059 :                               ofproto->mbridge, ofproto->sflow, ofproto->ipfix,
     614                 :      23059 :                               ofproto->netflow,
     615                 :      23059 :                               ofproto->up.forward_bpdu,
     616                 :      23059 :                               connmgr_has_in_band(ofproto->up.connmgr),
     617                 :      23059 :                               &ofproto->backer->support);
     618                 :            : 
     619 [ +  + ][ -  + ]:     122721 :             HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
     620                 :      99662 :                 xlate_bundle_set(ofproto, bundle, bundle->name,
     621                 :            :                                  bundle->vlan_mode, bundle->vlan,
     622                 :      99662 :                                  bundle->trunks, bundle->use_priority_tags,
     623                 :      99662 :                                  bundle->bond, bundle->lacp,
     624                 :      99662 :                                  bundle->floodable);
     625                 :            :             }
     626                 :            : 
     627 [ +  + ][ -  + ]:     123368 :             HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
     628                 :     200618 :                 int stp_port = ofport->stp_port
     629                 :         18 :                     ? stp_port_no(ofport->stp_port)
     630         [ +  + ]:     100309 :                     : -1;
     631                 :     100309 :                 xlate_ofport_set(ofproto, ofport->bundle, ofport,
     632                 :            :                                  ofport->up.ofp_port, ofport->odp_port,
     633                 :     100309 :                                  ofport->up.netdev, ofport->cfm, ofport->bfd,
     634                 :     100309 :                                  ofport->lldp, ofport->peer, stp_port,
     635                 :     100309 :                                  ofport->rstp_port, ofport->qdscp,
     636                 :            :                                  ofport->n_qdscp, ofport->up.pp.config,
     637                 :     100309 :                                  ofport->up.pp.state, ofport->is_tunnel,
     638                 :     100309 :                                  ofport->may_enable);
     639                 :            :             }
     640                 :      23059 :             xlate_txn_commit();
     641                 :            :         }
     642                 :            : 
     643                 :      18244 :         udpif_revalidate(backer->udpif);
     644                 :            :     }
     645                 :            : 
     646                 :     105699 :     process_dpif_port_changes(backer);
     647                 :            : 
     648                 :     105699 :     return 0;
     649                 :            : }
     650                 :            : 
     651                 :            : /* Check for and handle port changes in 'backer''s dpif. */
     652                 :            : static void
     653                 :     105699 : process_dpif_port_changes(struct dpif_backer *backer)
     654                 :            : {
     655                 :            :     for (;;) {
     656                 :            :         char *devname;
     657                 :            :         int error;
     658                 :            : 
     659                 :     107252 :         error = dpif_port_poll(backer->dpif, &devname);
     660   [ +  +  +  - ]:     107252 :         switch (error) {
     661                 :            :         case EAGAIN:
     662                 :     105699 :             return;
     663                 :            : 
     664                 :            :         case ENOBUFS:
     665                 :       1385 :             process_dpif_all_ports_changed(backer);
     666                 :       1385 :             break;
     667                 :            : 
     668                 :            :         case 0:
     669                 :        168 :             process_dpif_port_change(backer, devname);
     670                 :        168 :             free(devname);
     671                 :        168 :             break;
     672                 :            : 
     673                 :            :         default:
     674                 :          0 :             process_dpif_port_error(backer, error);
     675                 :          0 :             break;
     676                 :            :         }
     677                 :       1553 :     }
     678                 :            : }
     679                 :            : 
     680                 :            : static void
     681                 :       1385 : process_dpif_all_ports_changed(struct dpif_backer *backer)
     682                 :            : {
     683                 :            :     struct ofproto_dpif *ofproto;
     684                 :            :     struct dpif_port dpif_port;
     685                 :            :     struct dpif_port_dump dump;
     686                 :            :     struct sset devnames;
     687                 :            :     const char *devname;
     688                 :            : 
     689                 :       1385 :     sset_init(&devnames);
     690 [ +  + ][ -  + ]:       3180 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     691         [ +  - ]:       1795 :         if (ofproto->backer == backer) {
     692                 :            :             struct ofport *ofport;
     693                 :            : 
     694 [ +  + ][ -  + ]:       6674 :             HMAP_FOR_EACH (ofport, hmap_node, &ofproto->up.ports) {
     695                 :       4879 :                 sset_add(&devnames, netdev_get_name(ofport->netdev));
     696                 :            :             }
     697                 :            :         }
     698                 :            :     }
     699 [ +  + ][ +  + ]:       6604 :     DPIF_PORT_FOR_EACH (&dpif_port, &dump, backer->dpif) {
     700                 :       5219 :         sset_add(&devnames, dpif_port.name);
     701                 :            :     }
     702                 :            : 
     703 [ +  - ][ +  + ]:       7797 :     SSET_FOR_EACH (devname, &devnames) {
                 [ +  + ]
     704                 :       6412 :         process_dpif_port_change(backer, devname);
     705                 :            :     }
     706                 :       1385 :     sset_destroy(&devnames);
     707                 :       1385 : }
     708                 :            : 
     709                 :            : static void
     710                 :       6580 : process_dpif_port_change(struct dpif_backer *backer, const char *devname)
     711                 :            : {
     712                 :            :     struct ofproto_dpif *ofproto;
     713                 :            :     struct dpif_port port;
     714                 :            : 
     715                 :            :     /* Don't report on the datapath's device. */
     716         [ +  + ]:       6580 :     if (!strcmp(devname, dpif_base_name(backer->dpif))) {
     717                 :       1538 :         return;
     718                 :            :     }
     719                 :            : 
     720 [ +  + ][ -  + ]:      13442 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node,
     721                 :            :                    &all_ofproto_dpifs) {
     722         [ +  + ]:       8400 :         if (simap_contains(&ofproto->backer->tnl_backers, devname)) {
     723                 :        153 :             return;
     724                 :            :         }
     725                 :            :     }
     726                 :            : 
     727                 :       5042 :     ofproto = lookup_ofproto_dpif_by_port_name(devname);
     728         [ +  + ]:       5042 :     if (dpif_port_query_by_name(backer->dpif, devname, &port)) {
     729                 :            :         /* The port was removed.  If we know the datapath,
     730                 :            :          * report it through poll_set().  If we don't, it may be
     731                 :            :          * notifying us of a removal we initiated, so ignore it.
     732                 :            :          * If there's a pending ENOBUFS, let it stand, since
     733                 :            :          * everything will be reevaluated. */
     734 [ +  + ][ +  - ]:       1193 :         if (ofproto && ofproto->port_poll_errno != ENOBUFS) {
     735                 :          1 :             sset_add(&ofproto->port_poll_set, devname);
     736                 :       1193 :             ofproto->port_poll_errno = 0;
     737                 :            :         }
     738         [ -  + ]:       3849 :     } else if (!ofproto) {
     739                 :            :         /* The port was added, but we don't know with which
     740                 :            :          * ofproto we should associate it.  Delete it. */
     741                 :          0 :         dpif_port_del(backer->dpif, port.port_no);
     742                 :            :     } else {
     743                 :            :         struct ofport_dpif *ofport;
     744                 :            : 
     745                 :       3849 :         ofport = ofport_dpif_cast(shash_find_data(
     746                 :       3849 :                                       &ofproto->up.port_by_name, devname));
     747         [ +  - ]:       3849 :         if (ofport
     748         [ +  + ]:       3849 :             && ofport->odp_port != port.port_no
     749         [ +  - ]:          1 :             && !odp_port_to_ofport(backer, port.port_no))
     750                 :            :         {
     751                 :            :             /* 'ofport''s datapath port number has changed from
     752                 :            :              * 'ofport->odp_port' to 'port.port_no'.  Update our internal data
     753                 :            :              * structures to match. */
     754                 :          1 :             ovs_rwlock_wrlock(&backer->odp_to_ofport_lock);
     755                 :          1 :             hmap_remove(&backer->odp_to_ofport_map, &ofport->odp_port_node);
     756                 :          1 :             ofport->odp_port = port.port_no;
     757                 :          1 :             hmap_insert(&backer->odp_to_ofport_map, &ofport->odp_port_node,
     758                 :            :                         hash_odp_port(port.port_no));
     759                 :          1 :             ovs_rwlock_unlock(&backer->odp_to_ofport_lock);
     760                 :          1 :             backer->need_revalidate = REV_RECONFIGURE;
     761                 :            :         }
     762                 :            :     }
     763                 :       5042 :     dpif_port_destroy(&port);
     764                 :            : }
     765                 :            : 
     766                 :            : /* Propagate 'error' to all ofprotos based on 'backer'. */
     767                 :            : static void
     768                 :          0 : process_dpif_port_error(struct dpif_backer *backer, int error)
     769                 :            : {
     770                 :            :     struct ofproto_dpif *ofproto;
     771                 :            : 
     772 [ #  # ][ #  # ]:          0 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
     773         [ #  # ]:          0 :         if (ofproto->backer == backer) {
     774                 :          0 :             sset_clear(&ofproto->port_poll_set);
     775                 :          0 :             ofproto->port_poll_errno = error;
     776                 :            :         }
     777                 :            :     }
     778                 :          0 : }
     779                 :            : 
     780                 :            : static void
     781                 :     237444 : type_wait(const char *type)
     782                 :            : {
     783                 :            :     struct dpif_backer *backer;
     784                 :            : 
     785                 :     237444 :     backer = shash_find_data(&all_dpif_backers, type);
     786         [ +  + ]:     237444 :     if (!backer) {
     787                 :            :         /* This is not necessarily a problem, since backers are only
     788                 :            :          * created on demand. */
     789                 :     134755 :         return;
     790                 :            :     }
     791                 :            : 
     792                 :     102689 :     dpif_wait(backer->dpif);
     793                 :            : }
     794                 :            : 
     795                 :            : /* Basic life-cycle. */
     796                 :            : 
     797                 :            : static int add_internal_flows(struct ofproto_dpif *);
     798                 :            : 
     799                 :            : static struct ofproto *
     800                 :        749 : alloc(void)
     801                 :            : {
     802                 :        749 :     struct ofproto_dpif *ofproto = xzalloc(sizeof *ofproto);
     803                 :        749 :     return &ofproto->up;
     804                 :            : }
     805                 :            : 
     806                 :            : static void
     807                 :        123 : dealloc(struct ofproto *ofproto_)
     808                 :            : {
     809                 :        123 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
     810                 :        123 :     free(ofproto);
     811                 :        123 : }
     812                 :            : 
     813                 :            : static void
     814                 :        749 : close_dpif_backer(struct dpif_backer *backer)
     815                 :            : {
     816         [ -  + ]:        749 :     ovs_assert(backer->refcount > 0);
     817                 :            : 
     818         [ +  + ]:        749 :     if (--backer->refcount) {
     819                 :        135 :         return;
     820                 :            :     }
     821                 :            : 
     822                 :        614 :     udpif_destroy(backer->udpif);
     823                 :            : 
     824                 :        614 :     simap_destroy(&backer->tnl_backers);
     825                 :        614 :     ovs_rwlock_destroy(&backer->odp_to_ofport_lock);
     826                 :        614 :     hmap_destroy(&backer->odp_to_ofport_map);
     827                 :        614 :     shash_find_and_delete(&all_dpif_backers, backer->type);
     828                 :        614 :     free(backer->type);
     829                 :        614 :     free(backer->dp_version_string);
     830                 :        614 :     dpif_close(backer->dpif);
     831                 :        614 :     free(backer);
     832                 :            : }
     833                 :            : 
     834                 :            : /* Datapath port slated for removal from datapath. */
     835                 :            : struct odp_garbage {
     836                 :            :     struct ovs_list list_node;
     837                 :            :     odp_port_t odp_port;
     838                 :            : };
     839                 :            : 
     840                 :            : static bool check_variable_length_userdata(struct dpif_backer *backer);
     841                 :            : static void check_support(struct dpif_backer *backer);
     842                 :            : 
     843                 :            : static int
     844                 :        749 : open_dpif_backer(const char *type, struct dpif_backer **backerp)
     845                 :            : {
     846                 :            :     struct dpif_backer *backer;
     847                 :            :     struct dpif_port_dump port_dump;
     848                 :            :     struct dpif_port port;
     849                 :            :     struct shash_node *node;
     850                 :            :     struct ovs_list garbage_list;
     851                 :            :     struct odp_garbage *garbage;
     852                 :            : 
     853                 :            :     struct sset names;
     854                 :            :     char *backer_name;
     855                 :            :     const char *name;
     856                 :            :     int error;
     857                 :            : 
     858                 :        749 :     backer = shash_find_data(&all_dpif_backers, type);
     859         [ +  + ]:        749 :     if (backer) {
     860                 :        135 :         backer->refcount++;
     861                 :        135 :         *backerp = backer;
     862                 :        135 :         return 0;
     863                 :            :     }
     864                 :            : 
     865                 :        614 :     backer_name = xasprintf("ovs-%s", type);
     866                 :            : 
     867                 :            :     /* Remove any existing datapaths, since we assume we're the only
     868                 :            :      * userspace controlling the datapath. */
     869                 :        614 :     sset_init(&names);
     870                 :        614 :     dp_enumerate_names(type, &names);
     871 [ -  + ][ #  # ]:        614 :     SSET_FOR_EACH(name, &names) {
                 [ -  + ]
     872                 :            :         struct dpif *old_dpif;
     873                 :            : 
     874                 :            :         /* Don't remove our backer if it exists. */
     875         [ #  # ]:          0 :         if (!strcmp(name, backer_name)) {
     876                 :          0 :             continue;
     877                 :            :         }
     878                 :            : 
     879         [ #  # ]:          0 :         if (dpif_open(name, type, &old_dpif)) {
     880         [ #  # ]:          0 :             VLOG_WARN("couldn't open old datapath %s to remove it", name);
     881                 :            :         } else {
     882                 :          0 :             dpif_delete(old_dpif);
     883                 :          0 :             dpif_close(old_dpif);
     884                 :            :         }
     885                 :            :     }
     886                 :        614 :     sset_destroy(&names);
     887                 :            : 
     888                 :        614 :     backer = xmalloc(sizeof *backer);
     889                 :            : 
     890                 :        614 :     error = dpif_create_and_open(backer_name, type, &backer->dpif);
     891                 :        614 :     free(backer_name);
     892         [ -  + ]:        614 :     if (error) {
     893         [ #  # ]:          0 :         VLOG_ERR("failed to open datapath of type %s: %s", type,
     894                 :            :                  ovs_strerror(error));
     895                 :          0 :         free(backer);
     896                 :          0 :         return error;
     897                 :            :     }
     898                 :        614 :     backer->udpif = udpif_create(backer, backer->dpif);
     899                 :            : 
     900                 :        614 :     backer->type = xstrdup(type);
     901                 :        614 :     backer->refcount = 1;
     902                 :        614 :     hmap_init(&backer->odp_to_ofport_map);
     903                 :        614 :     ovs_rwlock_init(&backer->odp_to_ofport_lock);
     904                 :        614 :     backer->need_revalidate = 0;
     905                 :        614 :     simap_init(&backer->tnl_backers);
     906                 :        614 :     backer->recv_set_enable = !ofproto_get_flow_restore_wait();
     907                 :        614 :     *backerp = backer;
     908                 :            : 
     909         [ +  + ]:        614 :     if (backer->recv_set_enable) {
     910                 :        613 :         dpif_flow_flush(backer->dpif);
     911                 :            :     }
     912                 :            : 
     913                 :            :     /* Loop through the ports already on the datapath and remove any
     914                 :            :      * that we don't need anymore. */
     915                 :        614 :     ovs_list_init(&garbage_list);
     916                 :        614 :     dpif_port_dump_start(&port_dump, backer->dpif);
     917         [ +  + ]:       1228 :     while (dpif_port_dump_next(&port_dump, &port)) {
     918                 :        614 :         node = shash_find(&init_ofp_ports, port.name);
     919 [ +  - ][ -  + ]:        614 :         if (!node && strcmp(port.name, dpif_base_name(backer->dpif))) {
     920                 :          0 :             garbage = xmalloc(sizeof *garbage);
     921                 :          0 :             garbage->odp_port = port.port_no;
     922                 :          0 :             ovs_list_push_front(&garbage_list, &garbage->list_node);
     923                 :            :         }
     924                 :            :     }
     925                 :        614 :     dpif_port_dump_done(&port_dump);
     926                 :            : 
     927         [ -  + ]:        614 :     LIST_FOR_EACH_POP (garbage, list_node, &garbage_list) {
     928                 :          0 :         dpif_port_del(backer->dpif, garbage->odp_port);
     929                 :          0 :         free(garbage);
     930                 :            :     }
     931                 :            : 
     932                 :        614 :     shash_add(&all_dpif_backers, type, backer);
     933                 :            : 
     934                 :        614 :     check_support(backer);
     935                 :        614 :     atomic_count_init(&backer->tnl_count, 0);
     936                 :            : 
     937                 :        614 :     error = dpif_recv_set(backer->dpif, backer->recv_set_enable);
     938         [ -  + ]:        614 :     if (error) {
     939         [ #  # ]:          0 :         VLOG_ERR("failed to listen on datapath of type %s: %s",
     940                 :            :                  type, ovs_strerror(error));
     941                 :          0 :         close_dpif_backer(backer);
     942                 :          0 :         return error;
     943                 :            :     }
     944                 :            : 
     945         [ +  + ]:        614 :     if (backer->recv_set_enable) {
     946                 :        613 :         udpif_set_threads(backer->udpif, n_handlers, n_revalidators);
     947                 :            :     }
     948                 :            : 
     949                 :            :     /* This check fails if performed before udpif threads have been set,
     950                 :            :      * as the kernel module checks that the 'pid' in userspace action
     951                 :            :      * is non-zero. */
     952                 :            :     backer->support.variable_length_userdata
     953                 :        614 :         = check_variable_length_userdata(backer);
     954                 :        614 :     backer->dp_version_string = dpif_get_dp_version(backer->dpif);
     955                 :            : 
     956                 :        749 :     return error;
     957                 :            : }
     958                 :            : 
     959                 :            : bool
     960                 :    1473014 : ovs_native_tunneling_is_on(struct ofproto_dpif *ofproto)
     961                 :            : {
     962         [ +  + ]:    2919995 :     return ofproto_use_tnl_push_pop && ofproto->backer->support.tnl_push_pop &&
           [ +  +  +  + ]
     963                 :    1446982 :            atomic_count_get(&ofproto->backer->tnl_count);
     964                 :            : }
     965                 :            : 
     966                 :            : /* Tests whether 'backer''s datapath supports recirculation.  Only newer
     967                 :            :  * datapaths support OVS_KEY_ATTR_RECIRC_ID in keys.  We need to disable some
     968                 :            :  * features on older datapaths that don't support this feature.
     969                 :            :  *
     970                 :            :  * Returns false if 'backer' definitely does not support recirculation, true if
     971                 :            :  * it seems to support recirculation or if at least the error we get is
     972                 :            :  * ambiguous. */
     973                 :            : static bool
     974                 :        614 : check_recirc(struct dpif_backer *backer)
     975                 :            : {
     976                 :            :     struct flow flow;
     977                 :            :     struct odputil_keybuf keybuf;
     978                 :            :     struct ofpbuf key;
     979                 :            :     bool enable_recirc;
     980                 :        614 :     struct odp_flow_key_parms odp_parms = {
     981                 :            :         .flow = &flow,
     982                 :            :         .support = {
     983                 :            :             .recirc = true,
     984                 :            :         },
     985                 :            :     };
     986                 :            : 
     987                 :        614 :     memset(&flow, 0, sizeof flow);
     988                 :        614 :     flow.recirc_id = 1;
     989                 :        614 :     flow.dp_hash = 1;
     990                 :            : 
     991                 :        614 :     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
     992                 :        614 :     odp_flow_key_from_flow(&odp_parms, &key);
     993                 :        614 :     enable_recirc = dpif_probe_feature(backer->dpif, "recirculation", &key,
     994                 :            :                                        NULL);
     995                 :            : 
     996         [ +  - ]:        614 :     if (enable_recirc) {
     997         [ +  - ]:        614 :         VLOG_INFO("%s: Datapath supports recirculation",
     998                 :            :                   dpif_name(backer->dpif));
     999                 :            :     } else {
    1000         [ #  # ]:          0 :         VLOG_INFO("%s: Datapath does not support recirculation",
    1001                 :            :                   dpif_name(backer->dpif));
    1002                 :            :     }
    1003                 :            : 
    1004                 :        614 :     return enable_recirc;
    1005                 :            : }
    1006                 :            : 
    1007                 :            : /* Tests whether 'dpif' supports unique flow ids. We can skip serializing
    1008                 :            :  * some flow attributes for datapaths that support this feature.
    1009                 :            :  *
    1010                 :            :  * Returns true if 'dpif' supports UFID for flow operations.
    1011                 :            :  * Returns false if  'dpif' does not support UFID. */
    1012                 :            : static bool
    1013                 :        614 : check_ufid(struct dpif_backer *backer)
    1014                 :            : {
    1015                 :            :     struct flow flow;
    1016                 :            :     struct odputil_keybuf keybuf;
    1017                 :            :     struct ofpbuf key;
    1018                 :            :     ovs_u128 ufid;
    1019                 :            :     bool enable_ufid;
    1020                 :        614 :     struct odp_flow_key_parms odp_parms = {
    1021                 :            :         .flow = &flow,
    1022                 :            :     };
    1023                 :            : 
    1024                 :        614 :     memset(&flow, 0, sizeof flow);
    1025                 :        614 :     flow.dl_type = htons(0x1234);
    1026                 :            : 
    1027                 :        614 :     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
    1028                 :        614 :     odp_flow_key_from_flow(&odp_parms, &key);
    1029                 :        614 :     dpif_flow_hash(backer->dpif, key.data, key.size, &ufid);
    1030                 :            : 
    1031                 :        614 :     enable_ufid = dpif_probe_feature(backer->dpif, "UFID", &key, &ufid);
    1032                 :            : 
    1033         [ +  - ]:        614 :     if (enable_ufid) {
    1034         [ +  - ]:        614 :         VLOG_INFO("%s: Datapath supports unique flow ids",
    1035                 :            :                   dpif_name(backer->dpif));
    1036                 :            :     } else {
    1037         [ #  # ]:          0 :         VLOG_INFO("%s: Datapath does not support unique flow ids",
    1038                 :            :                   dpif_name(backer->dpif));
    1039                 :            :     }
    1040                 :        614 :     return enable_ufid;
    1041                 :            : }
    1042                 :            : 
    1043                 :            : /* Tests whether 'backer''s datapath supports variable-length
    1044                 :            :  * OVS_USERSPACE_ATTR_USERDATA in OVS_ACTION_ATTR_USERSPACE actions.  We need
    1045                 :            :  * to disable some features on older datapaths that don't support this
    1046                 :            :  * feature.
    1047                 :            :  *
    1048                 :            :  * Returns false if 'backer' definitely does not support variable-length
    1049                 :            :  * userdata, true if it seems to support them or if at least the error we get
    1050                 :            :  * is ambiguous. */
    1051                 :            : static bool
    1052                 :        614 : check_variable_length_userdata(struct dpif_backer *backer)
    1053                 :            : {
    1054                 :            :     struct eth_header *eth;
    1055                 :            :     struct ofpbuf actions;
    1056                 :            :     struct dpif_execute execute;
    1057                 :            :     struct dp_packet packet;
    1058                 :            :     struct flow flow;
    1059                 :            :     size_t start;
    1060                 :            :     int error;
    1061                 :            : 
    1062                 :            :     /* Compose a userspace action that will cause an ERANGE error on older
    1063                 :            :      * datapaths that don't support variable-length userdata.
    1064                 :            :      *
    1065                 :            :      * We really test for using userdata longer than 8 bytes, but older
    1066                 :            :      * datapaths accepted these, silently truncating the userdata to 8 bytes.
    1067                 :            :      * The same older datapaths rejected userdata shorter than 8 bytes, so we
    1068                 :            :      * test for that instead as a proxy for longer userdata support. */
    1069                 :        614 :     ofpbuf_init(&actions, 64);
    1070                 :        614 :     start = nl_msg_start_nested(&actions, OVS_ACTION_ATTR_USERSPACE);
    1071                 :        614 :     nl_msg_put_u32(&actions, OVS_USERSPACE_ATTR_PID,
    1072                 :        614 :                    dpif_port_get_pid(backer->dpif, ODPP_NONE, 0));
    1073                 :        614 :     nl_msg_put_unspec_zero(&actions, OVS_USERSPACE_ATTR_USERDATA, 4);
    1074                 :        614 :     nl_msg_end_nested(&actions, start);
    1075                 :            : 
    1076                 :            :     /* Compose a dummy ethernet packet. */
    1077                 :        614 :     dp_packet_init(&packet, ETH_HEADER_LEN);
    1078                 :        614 :     eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN);
    1079                 :        614 :     eth->eth_type = htons(0x1234);
    1080                 :            : 
    1081                 :        614 :     flow_extract(&packet, &flow);
    1082                 :            : 
    1083                 :            :     /* Execute the actions.  On older datapaths this fails with ERANGE, on
    1084                 :            :      * newer datapaths it succeeds. */
    1085                 :        614 :     execute.actions = actions.data;
    1086                 :        614 :     execute.actions_len = actions.size;
    1087                 :        614 :     execute.packet = &packet;
    1088                 :        614 :     execute.flow = &flow;
    1089                 :        614 :     execute.needs_help = false;
    1090                 :        614 :     execute.probe = true;
    1091                 :        614 :     execute.mtu = 0;
    1092                 :            : 
    1093                 :        614 :     error = dpif_execute(backer->dpif, &execute);
    1094                 :            : 
    1095                 :        614 :     dp_packet_uninit(&packet);
    1096                 :        614 :     ofpbuf_uninit(&actions);
    1097                 :            : 
    1098      [ +  -  - ]:        614 :     switch (error) {
    1099                 :            :     case 0:
    1100                 :        614 :         return true;
    1101                 :            : 
    1102                 :            :     case ERANGE:
    1103                 :            :         /* Variable-length userdata is not supported. */
    1104         [ #  # ]:          0 :         VLOG_WARN("%s: datapath does not support variable-length userdata "
    1105                 :            :                   "feature (needs Linux 3.10+ or kernel module from OVS "
    1106                 :            :                   "1..11+).  The NXAST_SAMPLE action will be ignored.",
    1107                 :            :                   dpif_name(backer->dpif));
    1108                 :          0 :         return false;
    1109                 :            : 
    1110                 :            :     default:
    1111                 :            :         /* Something odd happened.  We're not sure whether variable-length
    1112                 :            :          * userdata is supported.  Default to "yes". */
    1113         [ #  # ]:          0 :         VLOG_WARN("%s: variable-length userdata feature probe failed (%s)",
    1114                 :            :                   dpif_name(backer->dpif), ovs_strerror(error));
    1115                 :        614 :         return true;
    1116                 :            :     }
    1117                 :            : }
    1118                 :            : 
    1119                 :            : /* Tests the MPLS label stack depth supported by 'backer''s datapath.
    1120                 :            :  *
    1121                 :            :  * Returns the number of elements in a struct flow's mpls_lse field
    1122                 :            :  * if the datapath supports at least that many entries in an
    1123                 :            :  * MPLS label stack.
    1124                 :            :  * Otherwise returns the number of MPLS push actions supported by
    1125                 :            :  * the datapath. */
    1126                 :            : static size_t
    1127                 :        614 : check_max_mpls_depth(struct dpif_backer *backer)
    1128                 :            : {
    1129                 :            :     struct flow flow;
    1130                 :            :     int n;
    1131                 :            : 
    1132         [ +  + ]:       2330 :     for (n = 0; n < FLOW_MAX_MPLS_LABELS; n++) {
    1133                 :            :         struct odputil_keybuf keybuf;
    1134                 :            :         struct ofpbuf key;
    1135                 :       1779 :         struct odp_flow_key_parms odp_parms = {
    1136                 :            :             .flow = &flow,
    1137                 :            :         };
    1138                 :            : 
    1139                 :       1779 :         memset(&flow, 0, sizeof flow);
    1140                 :       1779 :         flow.dl_type = htons(ETH_TYPE_MPLS);
    1141                 :       1779 :         flow_set_mpls_bos(&flow, n, 1);
    1142                 :            : 
    1143                 :       1779 :         ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
    1144                 :       1779 :         odp_flow_key_from_flow(&odp_parms, &key);
    1145         [ +  + ]:       1779 :         if (!dpif_probe_feature(backer->dpif, "MPLS", &key, NULL)) {
    1146                 :         63 :             break;
    1147                 :            :         }
    1148                 :            :     }
    1149                 :            : 
    1150         [ +  - ]:        614 :     VLOG_INFO("%s: MPLS label stack length probed as %d",
    1151                 :            :               dpif_name(backer->dpif), n);
    1152                 :        614 :     return n;
    1153                 :            : }
    1154                 :            : 
    1155                 :            : /* Tests whether 'backer''s datapath supports masked data in
    1156                 :            :  * OVS_ACTION_ATTR_SET actions.  We need to disable some features on older
    1157                 :            :  * datapaths that don't support this feature. */
    1158                 :            : static bool
    1159                 :        614 : check_masked_set_action(struct dpif_backer *backer)
    1160                 :            : {
    1161                 :            :     struct eth_header *eth;
    1162                 :            :     struct ofpbuf actions;
    1163                 :            :     struct dpif_execute execute;
    1164                 :            :     struct dp_packet packet;
    1165                 :            :     struct flow flow;
    1166                 :            :     int error;
    1167                 :            :     struct ovs_key_ethernet key, mask;
    1168                 :            : 
    1169                 :            :     /* Compose a set action that will cause an EINVAL error on older
    1170                 :            :      * datapaths that don't support masked set actions.
    1171                 :            :      * Avoid using a full mask, as it could be translated to a non-masked
    1172                 :            :      * set action instead. */
    1173                 :        614 :     ofpbuf_init(&actions, 64);
    1174                 :        614 :     memset(&key, 0x53, sizeof key);
    1175                 :        614 :     memset(&mask, 0x7f, sizeof mask);
    1176                 :        614 :     commit_masked_set_action(&actions, OVS_KEY_ATTR_ETHERNET, &key, &mask,
    1177                 :            :                              sizeof key);
    1178                 :            : 
    1179                 :            :     /* Compose a dummy ethernet packet. */
    1180                 :        614 :     dp_packet_init(&packet, ETH_HEADER_LEN);
    1181                 :        614 :     eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN);
    1182                 :        614 :     eth->eth_type = htons(0x1234);
    1183                 :            : 
    1184                 :        614 :     flow_extract(&packet, &flow);
    1185                 :            : 
    1186                 :            :     /* Execute the actions.  On older datapaths this fails with EINVAL, on
    1187                 :            :      * newer datapaths it succeeds. */
    1188                 :        614 :     execute.actions = actions.data;
    1189                 :        614 :     execute.actions_len = actions.size;
    1190                 :        614 :     execute.packet = &packet;
    1191                 :        614 :     execute.flow = &flow;
    1192                 :        614 :     execute.needs_help = false;
    1193                 :        614 :     execute.probe = true;
    1194                 :        614 :     execute.mtu = 0;
    1195                 :            : 
    1196                 :        614 :     error = dpif_execute(backer->dpif, &execute);
    1197                 :            : 
    1198                 :        614 :     dp_packet_uninit(&packet);
    1199                 :        614 :     ofpbuf_uninit(&actions);
    1200                 :            : 
    1201         [ -  + ]:        614 :     if (error) {
    1202                 :            :         /* Masked set action is not supported. */
    1203         [ #  # ]:          0 :         VLOG_INFO("%s: datapath does not support masked set action feature.",
    1204                 :            :                   dpif_name(backer->dpif));
    1205                 :            :     }
    1206                 :        614 :     return !error;
    1207                 :            : }
    1208                 :            : 
    1209                 :            : /* Tests whether 'backer''s datapath supports truncation of a packet in
    1210                 :            :  * OVS_ACTION_ATTR_TRUNC.  We need to disable some features on older
    1211                 :            :  * datapaths that don't support this feature. */
    1212                 :            : static bool
    1213                 :        614 : check_trunc_action(struct dpif_backer *backer)
    1214                 :            : {
    1215                 :            :     struct eth_header *eth;
    1216                 :            :     struct ofpbuf actions;
    1217                 :            :     struct dpif_execute execute;
    1218                 :            :     struct dp_packet packet;
    1219                 :            :     struct ovs_action_trunc *trunc;
    1220                 :            :     struct flow flow;
    1221                 :            :     int error;
    1222                 :            : 
    1223                 :            :     /* Compose an action with output(port:1,
    1224                 :            :      *              max_len:OVS_ACTION_OUTPUT_MIN + 1).
    1225                 :            :      * This translates to one truncate action and one output action. */
    1226                 :        614 :     ofpbuf_init(&actions, 64);
    1227                 :        614 :     trunc = nl_msg_put_unspec_uninit(&actions,
    1228                 :            :                             OVS_ACTION_ATTR_TRUNC, sizeof *trunc);
    1229                 :            : 
    1230                 :        614 :     trunc->max_len = ETH_HEADER_LEN + 1;
    1231                 :        614 :     nl_msg_put_odp_port(&actions, OVS_ACTION_ATTR_OUTPUT, u32_to_odp(1));
    1232                 :            : 
    1233                 :            :     /* Compose a dummy Ethernet packet. */
    1234                 :        614 :     dp_packet_init(&packet, ETH_HEADER_LEN);
    1235                 :        614 :     eth = dp_packet_put_zeros(&packet, ETH_HEADER_LEN);
    1236                 :        614 :     eth->eth_type = htons(0x1234);
    1237                 :            : 
    1238                 :        614 :     flow_extract(&packet, &flow);
    1239                 :            : 
    1240                 :            :     /* Execute the actions.  On older datapaths this fails with EINVAL, on
    1241                 :            :      * newer datapaths it succeeds. */
    1242                 :        614 :     execute.actions = actions.data;
    1243                 :        614 :     execute.actions_len = actions.size;
    1244                 :        614 :     execute.packet = &packet;
    1245                 :        614 :     execute.flow = &flow;
    1246                 :        614 :     execute.needs_help = false;
    1247                 :        614 :     execute.probe = true;
    1248                 :        614 :     execute.mtu = 0;
    1249                 :            : 
    1250                 :        614 :     error = dpif_execute(backer->dpif, &execute);
    1251                 :            : 
    1252                 :        614 :     dp_packet_uninit(&packet);
    1253                 :        614 :     ofpbuf_uninit(&actions);
    1254                 :            : 
    1255         [ -  + ]:        614 :     if (error) {
    1256         [ #  # ]:          0 :         VLOG_INFO("%s: Datapath does not support truncate action",
    1257                 :            :                   dpif_name(backer->dpif));
    1258                 :            :     } else {
    1259         [ +  - ]:        614 :         VLOG_INFO("%s: Datapath supports truncate action",
    1260                 :            :                   dpif_name(backer->dpif));
    1261                 :            :     }
    1262                 :            : 
    1263                 :        614 :     return !error;
    1264                 :            : }
    1265                 :            : 
    1266                 :            : #define CHECK_FEATURE__(NAME, SUPPORT, FIELD, VALUE)                        \
    1267                 :            : static bool                                                                 \
    1268                 :            : check_##NAME(struct dpif_backer *backer)                                    \
    1269                 :            : {                                                                           \
    1270                 :            :     struct flow flow;                                                       \
    1271                 :            :     struct odputil_keybuf keybuf;                                           \
    1272                 :            :     struct ofpbuf key;                                                      \
    1273                 :            :     bool enable;                                                            \
    1274                 :            :     struct odp_flow_key_parms odp_parms = {                                 \
    1275                 :            :         .flow = &flow,                                                      \
    1276                 :            :         .support = {                                                        \
    1277                 :            :             .SUPPORT = true,                                                \
    1278                 :            :         },                                                                  \
    1279                 :            :     };                                                                      \
    1280                 :            :                                                                             \
    1281                 :            :     memset(&flow, 0, sizeof flow);                                          \
    1282                 :            :     flow.FIELD = VALUE;                                                     \
    1283                 :            :                                                                             \
    1284                 :            :     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);                         \
    1285                 :            :     odp_flow_key_from_flow(&odp_parms, &key);                               \
    1286                 :            :     enable = dpif_probe_feature(backer->dpif, #NAME, &key, NULL);           \
    1287                 :            :                                                                             \
    1288                 :            :     if (enable) {                                                           \
    1289                 :            :         VLOG_INFO("%s: Datapath supports "#NAME, dpif_name(backer->dpif));  \
    1290                 :            :     } else {                                                                \
    1291                 :            :         VLOG_INFO("%s: Datapath does not support "#NAME,                    \
    1292                 :            :                   dpif_name(backer->dpif));                                 \
    1293                 :            :     }                                                                       \
    1294                 :            :                                                                             \
    1295                 :            :     return enable;                                                          \
    1296                 :            : }
    1297                 :            : #define CHECK_FEATURE(FIELD) CHECK_FEATURE__(FIELD, FIELD, FIELD, 1)
    1298                 :            : 
    1299 [ +  - ][ +  - ]:       1228 : CHECK_FEATURE(ct_state)
                 [ #  # ]
    1300 [ +  - ][ +  - ]:       1228 : CHECK_FEATURE(ct_zone)
                 [ #  # ]
    1301 [ +  - ][ +  - ]:       1228 : CHECK_FEATURE(ct_mark)
                 [ #  # ]
    1302 [ +  - ][ +  - ]:       1228 : CHECK_FEATURE__(ct_label, ct_label, ct_label.u64.lo, 1)
                 [ #  # ]
    1303 [ +  + ][ +  - ]:       1228 : CHECK_FEATURE__(ct_state_nat, ct_state, ct_state, CS_TRACKED|CS_SRC_NAT)
                 [ +  - ]
    1304                 :            : 
    1305                 :            : #undef CHECK_FEATURE
    1306                 :            : #undef CHECK_FEATURE__
    1307                 :            : 
    1308                 :            : static void
    1309                 :        614 : check_support(struct dpif_backer *backer)
    1310                 :            : {
    1311                 :            :     /* This feature needs to be tested after udpif threads are set. */
    1312                 :        614 :     backer->support.variable_length_userdata = false;
    1313                 :            : 
    1314                 :        614 :     backer->support.odp.recirc = check_recirc(backer);
    1315                 :        614 :     backer->support.odp.max_mpls_depth = check_max_mpls_depth(backer);
    1316                 :        614 :     backer->support.masked_set_action = check_masked_set_action(backer);
    1317                 :        614 :     backer->support.trunc = check_trunc_action(backer);
    1318                 :        614 :     backer->support.ufid = check_ufid(backer);
    1319                 :        614 :     backer->support.tnl_push_pop = dpif_supports_tnl_push_pop(backer->dpif);
    1320                 :            : 
    1321                 :        614 :     backer->support.odp.ct_state = check_ct_state(backer);
    1322                 :        614 :     backer->support.odp.ct_zone = check_ct_zone(backer);
    1323                 :        614 :     backer->support.odp.ct_mark = check_ct_mark(backer);
    1324                 :        614 :     backer->support.odp.ct_label = check_ct_label(backer);
    1325                 :            : 
    1326                 :        614 :     backer->support.odp.ct_state_nat = check_ct_state_nat(backer);
    1327                 :        614 : }
    1328                 :            : 
    1329                 :            : static int
    1330                 :        749 : construct(struct ofproto *ofproto_)
    1331                 :            : {
    1332                 :        749 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1333                 :            :     struct shash_node *node, *next;
    1334                 :            :     int error;
    1335                 :            : 
    1336                 :            :     /* Tunnel module can get used right after the udpif threads are running. */
    1337                 :        749 :     ofproto_tunnel_init();
    1338                 :            : 
    1339                 :        749 :     error = open_dpif_backer(ofproto->up.type, &ofproto->backer);
    1340         [ -  + ]:        749 :     if (error) {
    1341                 :          0 :         return error;
    1342                 :            :     }
    1343                 :            : 
    1344                 :        749 :     uuid_generate(&ofproto->uuid);
    1345                 :        749 :     atomic_init(&ofproto->tables_version, OVS_VERSION_MIN);
    1346                 :        749 :     ofproto->netflow = NULL;
    1347                 :        749 :     ofproto->sflow = NULL;
    1348                 :        749 :     ofproto->ipfix = NULL;
    1349                 :        749 :     ofproto->stp = NULL;
    1350                 :        749 :     ofproto->rstp = NULL;
    1351                 :        749 :     ofproto->dump_seq = 0;
    1352                 :        749 :     hmap_init(&ofproto->bundles);
    1353                 :        749 :     ofproto->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
    1354                 :        749 :     ofproto->ms = NULL;
    1355                 :        749 :     ofproto->mbridge = mbridge_create();
    1356                 :        749 :     ofproto->has_bonded_bundles = false;
    1357                 :        749 :     ofproto->lacp_enabled = false;
    1358                 :        749 :     ovs_mutex_init_adaptive(&ofproto->stats_mutex);
    1359                 :            : 
    1360                 :        749 :     guarded_list_init(&ofproto->ams);
    1361                 :            : 
    1362                 :        749 :     sset_init(&ofproto->ports);
    1363                 :        749 :     sset_init(&ofproto->ghost_ports);
    1364                 :        749 :     sset_init(&ofproto->port_poll_set);
    1365                 :        749 :     ofproto->port_poll_errno = 0;
    1366                 :        749 :     ofproto->change_seq = 0;
    1367                 :        749 :     ofproto->ams_seq = seq_create();
    1368                 :        749 :     ofproto->ams_seqno = seq_read(ofproto->ams_seq);
    1369                 :            : 
    1370                 :            : 
    1371 [ +  + ][ -  + ]:        762 :     SHASH_FOR_EACH_SAFE (node, next, &init_ofp_ports) {
                 [ +  + ]
    1372                 :         13 :         struct iface_hint *iface_hint = node->data;
    1373                 :            : 
    1374         [ +  + ]:         13 :         if (!strcmp(iface_hint->br_name, ofproto->up.name)) {
    1375                 :            :             /* Check if the datapath already has this port. */
    1376         [ -  + ]:          9 :             if (dpif_port_exists(ofproto->backer->dpif, node->name)) {
    1377                 :          0 :                 sset_add(&ofproto->ports, node->name);
    1378                 :            :             }
    1379                 :            : 
    1380                 :          9 :             free(iface_hint->br_name);
    1381                 :          9 :             free(iface_hint->br_type);
    1382                 :          9 :             free(iface_hint);
    1383                 :          9 :             shash_delete(&init_ofp_ports, node);
    1384                 :            :         }
    1385                 :            :     }
    1386                 :            : 
    1387                 :        749 :     hmap_insert(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node,
    1388                 :            :                 hash_string(ofproto->up.name, 0));
    1389                 :        749 :     memset(&ofproto->stats, 0, sizeof ofproto->stats);
    1390                 :            : 
    1391                 :        749 :     ofproto_init_tables(ofproto_, N_TABLES);
    1392                 :        749 :     error = add_internal_flows(ofproto);
    1393                 :            : 
    1394                 :        749 :     ofproto->up.tables[TBL_INTERNAL].flags = OFTABLE_HIDDEN | OFTABLE_READONLY;
    1395                 :            : 
    1396                 :        749 :     return error;
    1397                 :            : }
    1398                 :            : 
    1399                 :            : static int
    1400                 :       2247 : add_internal_miss_flow(struct ofproto_dpif *ofproto, int id,
    1401                 :            :                   const struct ofpbuf *ofpacts, struct rule_dpif **rulep)
    1402                 :            : {
    1403                 :            :     struct match match;
    1404                 :            :     int error;
    1405                 :            :     struct rule *rule;
    1406                 :            : 
    1407                 :       2247 :     match_init_catchall(&match);
    1408                 :       2247 :     match_set_reg(&match, 0, id);
    1409                 :            : 
    1410                 :       2247 :     error = ofproto_dpif_add_internal_flow(ofproto, &match, 0, 0, ofpacts,
    1411                 :            :                                            &rule);
    1412         [ +  - ]:       2247 :     *rulep = error ? NULL : rule_dpif_cast(rule);
    1413                 :            : 
    1414                 :       2247 :     return error;
    1415                 :            : }
    1416                 :            : 
    1417                 :            : static int
    1418                 :        749 : add_internal_flows(struct ofproto_dpif *ofproto)
    1419                 :            : {
    1420                 :            :     struct ofpact_controller *controller;
    1421                 :            :     uint64_t ofpacts_stub[128 / 8];
    1422                 :            :     struct ofpbuf ofpacts;
    1423                 :            :     struct rule *unused_rulep OVS_UNUSED;
    1424                 :            :     struct match match;
    1425                 :            :     int error;
    1426                 :            :     int id;
    1427                 :            : 
    1428                 :        749 :     ofpbuf_use_stack(&ofpacts, ofpacts_stub, sizeof ofpacts_stub);
    1429                 :        749 :     id = 1;
    1430                 :            : 
    1431                 :        749 :     controller = ofpact_put_CONTROLLER(&ofpacts);
    1432                 :        749 :     controller->max_len = UINT16_MAX;
    1433                 :        749 :     controller->controller_id = 0;
    1434                 :        749 :     controller->reason = OFPR_IMPLICIT_MISS;
    1435                 :        749 :     ofpact_finish_CONTROLLER(&ofpacts, &controller);
    1436                 :            : 
    1437                 :        749 :     error = add_internal_miss_flow(ofproto, id++, &ofpacts,
    1438                 :            :                                    &ofproto->miss_rule);
    1439         [ -  + ]:        749 :     if (error) {
    1440                 :          0 :         return error;
    1441                 :            :     }
    1442                 :            : 
    1443                 :        749 :     ofpbuf_clear(&ofpacts);
    1444                 :        749 :     error = add_internal_miss_flow(ofproto, id++, &ofpacts,
    1445                 :            :                                    &ofproto->no_packet_in_rule);
    1446         [ -  + ]:        749 :     if (error) {
    1447                 :          0 :         return error;
    1448                 :            :     }
    1449                 :            : 
    1450                 :        749 :     error = add_internal_miss_flow(ofproto, id++, &ofpacts,
    1451                 :            :                                    &ofproto->drop_frags_rule);
    1452         [ -  + ]:        749 :     if (error) {
    1453                 :          0 :         return error;
    1454                 :            :     }
    1455                 :            : 
    1456                 :            :     /* Drop any run away non-recirc rule lookups. Recirc_id has to be
    1457                 :            :      * zero when reaching this rule.
    1458                 :            :      *
    1459                 :            :      * (priority=2), recirc_id=0, actions=drop
    1460                 :            :      */
    1461                 :        749 :     ofpbuf_clear(&ofpacts);
    1462                 :        749 :     match_init_catchall(&match);
    1463                 :        749 :     match_set_recirc_id(&match, 0);
    1464                 :        749 :     error = ofproto_dpif_add_internal_flow(ofproto, &match, 2, 0, &ofpacts,
    1465                 :            :                                            &unused_rulep);
    1466                 :        749 :     return error;
    1467                 :            : }
    1468                 :            : 
    1469                 :            : static void
    1470                 :        749 : destruct(struct ofproto *ofproto_)
    1471                 :            : {
    1472                 :        749 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1473                 :            :     struct ofproto_async_msg *am;
    1474                 :            :     struct rule_dpif *rule;
    1475                 :            :     struct oftable *table;
    1476                 :            :     struct ovs_list ams;
    1477                 :            : 
    1478                 :        749 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1479                 :        749 :     xlate_txn_start();
    1480                 :        749 :     xlate_remove_ofproto(ofproto);
    1481                 :        749 :     xlate_txn_commit();
    1482                 :            : 
    1483                 :            :     /* Ensure that the upcall processing threads have no remaining references
    1484                 :            :      * to the ofproto or anything in it. */
    1485                 :        749 :     udpif_synchronize(ofproto->backer->udpif);
    1486                 :            : 
    1487                 :        749 :     hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node);
    1488                 :            : 
    1489         [ +  + ]:     191744 :     OFPROTO_FOR_EACH_TABLE (table, &ofproto->up) {
    1490 [ +  + ][ +  + ]:     195271 :         CLS_FOR_EACH (rule, up.cr, &table->cls) {
    1491                 :       4276 :             ofproto_rule_delete(&ofproto->up, &rule->up);
    1492                 :            :         }
    1493                 :            :     }
    1494                 :        749 :     ofproto_group_delete_all(&ofproto->up);
    1495                 :            : 
    1496                 :        749 :     guarded_list_pop_all(&ofproto->ams, &ams);
    1497         [ -  + ]:        749 :     LIST_FOR_EACH_POP (am, list_node, &ams) {
    1498                 :          0 :         ofproto_async_msg_free(am);
    1499                 :            :     }
    1500                 :        749 :     guarded_list_destroy(&ofproto->ams);
    1501                 :            : 
    1502                 :        749 :     recirc_free_ofproto(ofproto, ofproto->up.name);
    1503                 :            : 
    1504                 :        749 :     mbridge_unref(ofproto->mbridge);
    1505                 :            : 
    1506                 :        749 :     netflow_unref(ofproto->netflow);
    1507                 :        749 :     dpif_sflow_unref(ofproto->sflow);
    1508                 :        749 :     dpif_ipfix_unref(ofproto->ipfix);
    1509                 :        749 :     hmap_destroy(&ofproto->bundles);
    1510                 :        749 :     mac_learning_unref(ofproto->ml);
    1511                 :        749 :     mcast_snooping_unref(ofproto->ms);
    1512                 :            : 
    1513                 :        749 :     sset_destroy(&ofproto->ports);
    1514                 :        749 :     sset_destroy(&ofproto->ghost_ports);
    1515                 :        749 :     sset_destroy(&ofproto->port_poll_set);
    1516                 :            : 
    1517                 :        749 :     ovs_mutex_destroy(&ofproto->stats_mutex);
    1518                 :            : 
    1519                 :        749 :     seq_destroy(ofproto->ams_seq);
    1520                 :            : 
    1521                 :        749 :     close_dpif_backer(ofproto->backer);
    1522                 :        749 : }
    1523                 :            : 
    1524                 :            : static int
    1525                 :     157605 : run(struct ofproto *ofproto_)
    1526                 :            : {
    1527                 :     157605 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1528                 :            :     uint64_t new_seq, new_dump_seq;
    1529                 :            : 
    1530         [ -  + ]:     157605 :     if (mbridge_need_revalidate(ofproto->mbridge)) {
    1531                 :          0 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1532                 :          0 :         ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    1533                 :          0 :         mac_learning_flush(ofproto->ml);
    1534                 :          0 :         ovs_rwlock_unlock(&ofproto->ml->rwlock);
    1535                 :          0 :         mcast_snooping_mdb_flush(ofproto->ms);
    1536                 :            :     }
    1537                 :            : 
    1538                 :            :     /* Always updates the ofproto->ams_seqno to avoid frequent wakeup during
    1539                 :            :      * flow restore.  Even though nothing is processed during flow restore,
    1540                 :            :      * all queued 'ams' will be handled immediately when flow restore
    1541                 :            :      * completes. */
    1542                 :     157605 :     ofproto->ams_seqno = seq_read(ofproto->ams_seq);
    1543                 :            : 
    1544                 :            :     /* Do not perform any periodic activity required by 'ofproto' while
    1545                 :            :      * waiting for flow restore to complete. */
    1546         [ +  + ]:     157605 :     if (!ofproto_get_flow_restore_wait()) {
    1547                 :            :         struct ofproto_async_msg *am;
    1548                 :            :         struct ovs_list ams;
    1549                 :            : 
    1550                 :     157527 :         guarded_list_pop_all(&ofproto->ams, &ams);
    1551         [ +  + ]:     158578 :         LIST_FOR_EACH_POP (am, list_node, &ams) {
    1552                 :       1051 :             connmgr_send_async_msg(ofproto->up.connmgr, am);
    1553                 :       1051 :             ofproto_async_msg_free(am);
    1554                 :            :         }
    1555                 :            :     }
    1556                 :            : 
    1557         [ +  + ]:     157605 :     if (ofproto->netflow) {
    1558                 :       1336 :         netflow_run(ofproto->netflow);
    1559                 :            :     }
    1560         [ +  + ]:     157605 :     if (ofproto->sflow) {
    1561                 :        425 :         dpif_sflow_run(ofproto->sflow);
    1562                 :            :     }
    1563         [ +  + ]:     157605 :     if (ofproto->ipfix) {
    1564                 :        287 :         dpif_ipfix_run(ofproto->ipfix);
    1565                 :            :     }
    1566                 :            : 
    1567                 :     157605 :     new_seq = seq_read(connectivity_seq_get());
    1568         [ +  + ]:     157605 :     if (ofproto->change_seq != new_seq) {
    1569                 :            :         struct ofport_dpif *ofport;
    1570                 :            : 
    1571 [ +  + ][ -  + ]:      41960 :         HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
    1572                 :      35828 :             port_run(ofport);
    1573                 :            :         }
    1574                 :            : 
    1575                 :       6132 :         ofproto->change_seq = new_seq;
    1576                 :            :     }
    1577 [ +  + ][ +  + ]:     157605 :     if (ofproto->lacp_enabled || ofproto->has_bonded_bundles) {
    1578                 :            :         struct ofbundle *bundle;
    1579                 :            : 
    1580 [ +  + ][ -  + ]:      20948 :         HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
    1581                 :      15523 :             bundle_run(bundle);
    1582                 :            :         }
    1583                 :            :     }
    1584                 :            : 
    1585                 :     157605 :     stp_run(ofproto);
    1586                 :     157605 :     rstp_run(ofproto);
    1587                 :     157605 :     ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    1588         [ +  + ]:     157605 :     if (mac_learning_run(ofproto->ml)) {
    1589                 :        569 :         ofproto->backer->need_revalidate = REV_MAC_LEARNING;
    1590                 :            :     }
    1591                 :     157605 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    1592                 :            : 
    1593         [ -  + ]:     157605 :     if (mcast_snooping_run(ofproto->ms)) {
    1594                 :          0 :         ofproto->backer->need_revalidate = REV_MCAST_SNOOPING;
    1595                 :            :     }
    1596                 :            : 
    1597                 :     157605 :     new_dump_seq = seq_read(udpif_dump_seq(ofproto->backer->udpif));
    1598         [ +  + ]:     157605 :     if (ofproto->dump_seq != new_dump_seq) {
    1599                 :            :         struct rule *rule, *next_rule;
    1600                 :      38106 :         long long now = time_msec();
    1601                 :            : 
    1602                 :            :         /* We know stats are relatively fresh, so now is a good time to do some
    1603                 :            :          * periodic work. */
    1604                 :      38106 :         ofproto->dump_seq = new_dump_seq;
    1605                 :            : 
    1606                 :            :         /* Expire OpenFlow flows whose idle_timeout or hard_timeout
    1607                 :            :          * has passed. */
    1608                 :      38106 :         ovs_mutex_lock(&ofproto_mutex);
    1609 [ +  + ][ +  + ]:      38480 :         LIST_FOR_EACH_SAFE (rule, next_rule, expirable,
    1610                 :            :                             &ofproto->up.expirable) {
    1611                 :        374 :             rule_expire(rule_dpif_cast(rule), now);
    1612                 :            :         }
    1613                 :      38106 :         ovs_mutex_unlock(&ofproto_mutex);
    1614                 :            : 
    1615                 :            :         /* All outstanding data in existing flows has been accounted, so it's a
    1616                 :            :          * good time to do bond rebalancing. */
    1617         [ +  + ]:      38106 :         if (ofproto->has_bonded_bundles) {
    1618                 :            :             struct ofbundle *bundle;
    1619                 :            : 
    1620 [ +  + ][ -  + ]:       3866 :             HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
    1621         [ +  + ]:       2803 :                 if (bundle->bond) {
    1622                 :       1063 :                     bond_rebalance(bundle->bond);
    1623                 :            :                 }
    1624                 :            :             }
    1625                 :            :         }
    1626                 :            :     }
    1627                 :     157605 :     return 0;
    1628                 :            : }
    1629                 :            : 
    1630                 :            : static void
    1631                 :     153645 : ofproto_dpif_wait(struct ofproto *ofproto_)
    1632                 :            : {
    1633                 :     153645 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1634                 :            : 
    1635         [ +  + ]:     153645 :     if (ofproto_get_flow_restore_wait()) {
    1636                 :         78 :         return;
    1637                 :            :     }
    1638                 :            : 
    1639         [ +  + ]:     153567 :     if (ofproto->sflow) {
    1640                 :        425 :         dpif_sflow_wait(ofproto->sflow);
    1641                 :            :     }
    1642         [ +  + ]:     153567 :     if (ofproto->ipfix) {
    1643                 :        283 :         dpif_ipfix_wait(ofproto->ipfix);
    1644                 :            :     }
    1645 [ +  + ][ +  + ]:     153567 :     if (ofproto->lacp_enabled || ofproto->has_bonded_bundles) {
    1646                 :            :         struct ofbundle *bundle;
    1647                 :            : 
    1648 [ +  + ][ -  + ]:      20907 :         HMAP_FOR_EACH (bundle, hmap_node, &ofproto->bundles) {
    1649                 :      15495 :             bundle_wait(bundle);
    1650                 :            :         }
    1651                 :            :     }
    1652         [ +  + ]:     153567 :     if (ofproto->netflow) {
    1653                 :       1336 :         netflow_wait(ofproto->netflow);
    1654                 :            :     }
    1655                 :     153567 :     ovs_rwlock_rdlock(&ofproto->ml->rwlock);
    1656                 :     153567 :     mac_learning_wait(ofproto->ml);
    1657                 :     153567 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    1658                 :     153567 :     mcast_snooping_wait(ofproto->ms);
    1659                 :     153567 :     stp_wait(ofproto);
    1660         [ +  + ]:     153567 :     if (ofproto->backer->need_revalidate) {
    1661                 :      17508 :         poll_immediate_wake();
    1662                 :            :     }
    1663                 :            : 
    1664                 :     153567 :     seq_wait(udpif_dump_seq(ofproto->backer->udpif), ofproto->dump_seq);
    1665                 :     153567 :     seq_wait(ofproto->ams_seq, ofproto->ams_seqno);
    1666                 :            : }
    1667                 :            : 
    1668                 :            : static void
    1669                 :        162 : type_get_memory_usage(const char *type, struct simap *usage)
    1670                 :            : {
    1671                 :            :     struct dpif_backer *backer;
    1672                 :            : 
    1673                 :        162 :     backer = shash_find_data(&all_dpif_backers, type);
    1674         [ +  + ]:        162 :     if (backer) {
    1675                 :         72 :         udpif_get_memory_usage(backer->udpif, usage);
    1676                 :            :     }
    1677                 :        162 : }
    1678                 :            : 
    1679                 :            : static void
    1680                 :        895 : flush(struct ofproto *ofproto_)
    1681                 :            : {
    1682                 :        895 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1683                 :        895 :     struct dpif_backer *backer = ofproto->backer;
    1684                 :            : 
    1685         [ +  - ]:        895 :     if (backer) {
    1686                 :        895 :         udpif_flush(backer->udpif);
    1687                 :            :     }
    1688                 :        895 : }
    1689                 :            : 
    1690                 :            : static void
    1691                 :         82 : query_tables(struct ofproto *ofproto,
    1692                 :            :              struct ofputil_table_features *features,
    1693                 :            :              struct ofputil_table_stats *stats)
    1694                 :            : {
    1695                 :         82 :     strcpy(features->name, "classifier");
    1696                 :            : 
    1697         [ +  + ]:         82 :     if (stats) {
    1698                 :            :         int i;
    1699                 :            : 
    1700         [ +  + ]:       2560 :         for (i = 0; i < ofproto->n_tables; i++) {
    1701                 :            :             unsigned long missed, matched;
    1702                 :            : 
    1703                 :       2550 :             atomic_read_relaxed(&ofproto->tables[i].n_matched, &matched);
    1704                 :       2550 :             atomic_read_relaxed(&ofproto->tables[i].n_missed, &missed);
    1705                 :            : 
    1706                 :       2550 :             stats[i].matched_count = matched;
    1707                 :       2550 :             stats[i].lookup_count = matched + missed;
    1708                 :            :         }
    1709                 :            :     }
    1710                 :         82 : }
    1711                 :            : 
    1712                 :            : static void
    1713                 :      41413 : set_tables_version(struct ofproto *ofproto_, ovs_version_t version)
    1714                 :            : {
    1715                 :      41413 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1716                 :            : 
    1717                 :      41413 :     atomic_store_relaxed(&ofproto->tables_version, version);
    1718                 :      41413 :     ofproto->backer->need_revalidate = REV_FLOW_TABLE;
    1719                 :      41413 : }
    1720                 :            : 
    1721                 :            : static struct ofport *
    1722                 :       2690 : port_alloc(void)
    1723                 :            : {
    1724                 :       2690 :     struct ofport_dpif *port = xzalloc(sizeof *port);
    1725                 :       2690 :     return &port->up;
    1726                 :            : }
    1727                 :            : 
    1728                 :            : static void
    1729                 :       2690 : port_dealloc(struct ofport *port_)
    1730                 :            : {
    1731                 :       2690 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    1732                 :       2690 :     free(port);
    1733                 :       2690 : }
    1734                 :            : 
    1735                 :            : static int
    1736                 :       2690 : port_construct(struct ofport *port_)
    1737                 :            : {
    1738                 :       2690 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    1739                 :       2690 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
    1740                 :       2690 :     const struct netdev *netdev = port->up.netdev;
    1741                 :            :     char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
    1742                 :            :     const char *dp_port_name;
    1743                 :            :     struct dpif_port dpif_port;
    1744                 :            :     int error;
    1745                 :            : 
    1746                 :       2690 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1747                 :       2690 :     port->bundle = NULL;
    1748                 :       2690 :     port->cfm = NULL;
    1749                 :       2690 :     port->bfd = NULL;
    1750                 :       2690 :     port->lldp = NULL;
    1751                 :       2690 :     port->may_enable = false;
    1752                 :       2690 :     port->stp_port = NULL;
    1753                 :       2690 :     port->stp_state = STP_DISABLED;
    1754                 :       2690 :     port->rstp_port = NULL;
    1755                 :       2690 :     port->rstp_state = RSTP_DISABLED;
    1756                 :       2690 :     port->is_tunnel = false;
    1757                 :       2690 :     port->peer = NULL;
    1758                 :       2690 :     port->qdscp = NULL;
    1759                 :       2690 :     port->n_qdscp = 0;
    1760                 :       2690 :     port->carrier_seq = netdev_get_carrier_resets(netdev);
    1761                 :       2690 :     port->is_layer3 = netdev_vport_is_layer3(netdev);
    1762                 :            : 
    1763         [ +  + ]:       2690 :     if (netdev_vport_is_patch(netdev)) {
    1764                 :            :         /* By bailing out here, we don't submit the port to the sFlow module
    1765                 :            :          * to be considered for counter polling export.  This is correct
    1766                 :            :          * because the patch port represents an interface that sFlow considers
    1767                 :            :          * to be "internal" to the switch as a whole, and therefore not a
    1768                 :            :          * candidate for counter polling. */
    1769                 :        322 :         port->odp_port = ODPP_NONE;
    1770                 :        322 :         ofport_update_peer(port);
    1771                 :        322 :         return 0;
    1772                 :            :     }
    1773                 :            : 
    1774                 :       2368 :     dp_port_name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
    1775                 :       2368 :     error = dpif_port_query_by_name(ofproto->backer->dpif, dp_port_name,
    1776                 :            :                                     &dpif_port);
    1777         [ -  + ]:       2368 :     if (error) {
    1778                 :          0 :         return error;
    1779                 :            :     }
    1780                 :            : 
    1781                 :       2368 :     port->odp_port = dpif_port.port_no;
    1782                 :            : 
    1783         [ +  + ]:       2368 :     if (netdev_get_tunnel_config(netdev)) {
    1784                 :        320 :         atomic_count_inc(&ofproto->backer->tnl_count);
    1785                 :        320 :         error = tnl_port_add(port, port->up.netdev, port->odp_port,
    1786                 :        320 :                              ovs_native_tunneling_is_on(ofproto), dp_port_name);
    1787         [ +  + ]:        320 :         if (error) {
    1788                 :          1 :             atomic_count_dec(&ofproto->backer->tnl_count);
    1789                 :          1 :             dpif_port_destroy(&dpif_port);
    1790                 :          1 :             return error;
    1791                 :            :         }
    1792                 :            : 
    1793                 :        319 :         port->is_tunnel = true;
    1794         [ -  + ]:        319 :         if (ofproto->ipfix) {
    1795                 :        319 :            dpif_ipfix_add_tunnel_port(ofproto->ipfix, port_, port->odp_port);
    1796                 :            :         }
    1797                 :            :     } else {
    1798                 :            :         /* Sanity-check that a mapping doesn't already exist.  This
    1799                 :            :          * shouldn't happen for non-tunnel ports. */
    1800         [ -  + ]:       2048 :         if (odp_port_to_ofp_port(ofproto, port->odp_port) != OFPP_NONE) {
    1801         [ #  # ]:          0 :             VLOG_ERR("port %s already has an OpenFlow port number",
    1802                 :            :                      dpif_port.name);
    1803                 :          0 :             dpif_port_destroy(&dpif_port);
    1804                 :          0 :             return EBUSY;
    1805                 :            :         }
    1806                 :            : 
    1807                 :       2048 :         ovs_rwlock_wrlock(&ofproto->backer->odp_to_ofport_lock);
    1808                 :       2048 :         hmap_insert(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node,
    1809                 :            :                     hash_odp_port(port->odp_port));
    1810                 :       2048 :         ovs_rwlock_unlock(&ofproto->backer->odp_to_ofport_lock);
    1811                 :            :     }
    1812                 :       2367 :     dpif_port_destroy(&dpif_port);
    1813                 :            : 
    1814         [ -  + ]:       2367 :     if (ofproto->sflow) {
    1815                 :          0 :         dpif_sflow_add_port(ofproto->sflow, port_, port->odp_port);
    1816                 :            :     }
    1817                 :            : 
    1818                 :       2690 :     return 0;
    1819                 :            : }
    1820                 :            : 
    1821                 :            : static void
    1822                 :       2689 : port_destruct(struct ofport *port_, bool del)
    1823                 :            : {
    1824                 :       2689 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    1825                 :       2689 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
    1826                 :       2689 :     const char *devname = netdev_get_name(port->up.netdev);
    1827                 :            :     char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
    1828                 :            :     const char *dp_port_name;
    1829                 :            : 
    1830                 :       2689 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1831                 :       2689 :     xlate_txn_start();
    1832                 :       2689 :     xlate_ofport_remove(port);
    1833                 :       2689 :     xlate_txn_commit();
    1834                 :            : 
    1835                 :       2689 :     dp_port_name = netdev_vport_get_dpif_port(port->up.netdev, namebuf,
    1836                 :            :                                               sizeof namebuf);
    1837 [ +  + ][ +  + ]:       2689 :     if (del && dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
    1838                 :            :         /* The underlying device is still there, so delete it.  This
    1839                 :            :          * happens when the ofproto is being destroyed, since the caller
    1840                 :            :          * assumes that removal of attached ports will happen as part of
    1841                 :            :          * destruction. */
    1842         [ +  + ]:         61 :         if (!port->is_tunnel) {
    1843                 :         15 :             dpif_port_del(ofproto->backer->dpif, port->odp_port);
    1844                 :            :         }
    1845                 :            :     }
    1846                 :            : 
    1847         [ +  + ]:       2689 :     if (port->peer) {
    1848                 :        158 :         port->peer->peer = NULL;
    1849                 :        158 :         port->peer = NULL;
    1850                 :            :     }
    1851                 :            : 
    1852 [ +  + ][ +  + ]:       2689 :     if (port->odp_port != ODPP_NONE && !port->is_tunnel) {
    1853                 :       2048 :         ovs_rwlock_wrlock(&ofproto->backer->odp_to_ofport_lock);
    1854                 :       2048 :         hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
    1855                 :       2048 :         ovs_rwlock_unlock(&ofproto->backer->odp_to_ofport_lock);
    1856                 :            :     }
    1857                 :            : 
    1858         [ +  + ]:       2689 :     if (port->is_tunnel) {
    1859                 :        319 :         atomic_count_dec(&ofproto->backer->tnl_count);
    1860                 :            :     }
    1861                 :            : 
    1862 [ +  + ][ -  + ]:       2689 :     if (port->is_tunnel && ofproto->ipfix) {
    1863                 :          0 :        dpif_ipfix_del_tunnel_port(ofproto->ipfix, port->odp_port);
    1864                 :            :     }
    1865                 :            : 
    1866                 :       2689 :     tnl_port_del(port);
    1867                 :       2689 :     sset_find_and_delete(&ofproto->ports, devname);
    1868                 :       2689 :     sset_find_and_delete(&ofproto->ghost_ports, devname);
    1869                 :       2689 :     bundle_remove(port_);
    1870                 :       2689 :     set_cfm(port_, NULL);
    1871                 :       2689 :     set_bfd(port_, NULL);
    1872                 :       2689 :     set_lldp(port_, NULL);
    1873         [ -  + ]:       2689 :     if (port->stp_port) {
    1874                 :          0 :         stp_port_disable(port->stp_port);
    1875                 :            :     }
    1876                 :       2689 :     set_rstp_port(port_, NULL);
    1877         [ +  + ]:       2689 :     if (ofproto->sflow) {
    1878                 :         18 :         dpif_sflow_del_port(ofproto->sflow, port->odp_port);
    1879                 :            :     }
    1880                 :            : 
    1881                 :       2689 :     free(port->qdscp);
    1882                 :       2689 : }
    1883                 :            : 
    1884                 :            : static void
    1885                 :       5006 : port_modified(struct ofport *port_)
    1886                 :            : {
    1887                 :       5006 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    1888                 :            :     char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
    1889                 :            :     const char *dp_port_name;
    1890                 :       5006 :     struct netdev *netdev = port->up.netdev;
    1891                 :            : 
    1892 [ +  - ][ +  + ]:       5006 :     if (port->bundle && port->bundle->bond) {
    1893                 :         36 :         bond_slave_set_netdev(port->bundle->bond, port, netdev);
    1894                 :            :     }
    1895                 :            : 
    1896         [ -  + ]:       5006 :     if (port->cfm) {
    1897                 :          0 :         cfm_set_netdev(port->cfm, netdev);
    1898                 :            :     }
    1899                 :            : 
    1900         [ +  + ]:       5006 :     if (port->bfd) {
    1901                 :          1 :         bfd_set_netdev(port->bfd, netdev);
    1902                 :            :     }
    1903                 :            : 
    1904                 :       5006 :     ofproto_dpif_monitor_port_update(port, port->bfd, port->cfm,
    1905                 :       5006 :                                      port->lldp, &port->up.pp.hw_addr);
    1906                 :            : 
    1907                 :       5006 :     dp_port_name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
    1908                 :            : 
    1909         [ +  + ]:       5006 :     if (port->is_tunnel) {
    1910                 :          5 :         struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
    1911                 :            : 
    1912         [ -  + ]:          5 :         if (tnl_port_reconfigure(port, netdev, port->odp_port,
    1913                 :          5 :                                  ovs_native_tunneling_is_on(ofproto),
    1914                 :            :                                  dp_port_name)) {
    1915                 :          0 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1916                 :            :         }
    1917                 :            :     }
    1918                 :            : 
    1919                 :       5006 :     ofport_update_peer(port);
    1920                 :       5006 : }
    1921                 :            : 
    1922                 :            : static void
    1923                 :         39 : port_reconfigured(struct ofport *port_, enum ofputil_port_config old_config)
    1924                 :            : {
    1925                 :         39 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    1926                 :         39 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
    1927                 :         39 :     enum ofputil_port_config changed = old_config ^ port->up.pp.config;
    1928                 :            : 
    1929         [ +  + ]:         39 :     if (changed & (OFPUTIL_PC_NO_RECV | OFPUTIL_PC_NO_RECV_STP |
    1930                 :            :                    OFPUTIL_PC_NO_FWD | OFPUTIL_PC_NO_FLOOD |
    1931                 :            :                    OFPUTIL_PC_NO_PACKET_IN)) {
    1932                 :         22 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1933                 :            : 
    1934 [ +  + ][ +  - ]:         22 :         if (changed & OFPUTIL_PC_NO_FLOOD && port->bundle) {
    1935                 :          3 :             bundle_update(port->bundle);
    1936                 :            :         }
    1937                 :            :     }
    1938                 :         39 : }
    1939                 :            : 
    1940                 :            : static int
    1941                 :       4700 : set_sflow(struct ofproto *ofproto_,
    1942                 :            :           const struct ofproto_sflow_options *sflow_options)
    1943                 :            : {
    1944                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1945                 :       4700 :     struct dpif_sflow *ds = ofproto->sflow;
    1946                 :            : 
    1947         [ +  + ]:       4700 :     if (sflow_options) {
    1948         [ -  + ]:          6 :         uint32_t old_probability = ds ? dpif_sflow_get_probability(ds) : 0;
    1949         [ +  - ]:          6 :         if (!ds) {
    1950                 :            :             struct ofport_dpif *ofport;
    1951                 :            : 
    1952                 :          6 :             ds = ofproto->sflow = dpif_sflow_create();
    1953 [ +  + ][ -  + ]:         24 :             HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
    1954                 :         18 :                 dpif_sflow_add_port(ds, &ofport->up, ofport->odp_port);
    1955                 :            :             }
    1956                 :            :         }
    1957                 :          6 :         dpif_sflow_set_options(ds, sflow_options);
    1958         [ +  - ]:          6 :         if (dpif_sflow_get_probability(ds) != old_probability) {
    1959                 :          6 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1960                 :            :         }
    1961                 :            :     } else {
    1962         [ -  + ]:       4694 :         if (ds) {
    1963                 :          0 :             dpif_sflow_unref(ds);
    1964                 :          0 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    1965                 :          0 :             ofproto->sflow = NULL;
    1966                 :            :         }
    1967                 :            :     }
    1968                 :       4700 :     return 0;
    1969                 :            : }
    1970                 :            : 
    1971                 :            : static int
    1972                 :       4700 : set_ipfix(
    1973                 :            :     struct ofproto *ofproto_,
    1974                 :            :     const struct ofproto_ipfix_bridge_exporter_options *bridge_exporter_options,
    1975                 :            :     const struct ofproto_ipfix_flow_exporter_options *flow_exporters_options,
    1976                 :            :     size_t n_flow_exporters_options)
    1977                 :            : {
    1978                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    1979                 :       4700 :     struct dpif_ipfix *di = ofproto->ipfix;
    1980 [ +  + ][ +  + ]:       4700 :     bool has_options = bridge_exporter_options || flow_exporters_options;
    1981                 :       4700 :     bool new_di = false;
    1982                 :            : 
    1983 [ +  + ][ +  - ]:       4700 :     if (has_options && !di) {
    1984                 :          5 :         di = ofproto->ipfix = dpif_ipfix_create();
    1985                 :          5 :         new_di = true;
    1986                 :            :     }
    1987                 :            : 
    1988         [ +  + ]:       4700 :     if (di) {
    1989                 :            :         /* Call set_options in any case to cleanly flush the flow
    1990                 :            :          * caches in the last exporters that are to be destroyed. */
    1991                 :          9 :         dpif_ipfix_set_options(
    1992                 :            :             di, bridge_exporter_options, flow_exporters_options,
    1993                 :            :             n_flow_exporters_options);
    1994                 :            : 
    1995                 :            :         /* Add tunnel ports only when a new ipfix created */
    1996         [ +  + ]:          9 :         if (new_di == true) {
    1997                 :            :             struct ofport_dpif *ofport;
    1998 [ +  + ][ -  + ]:         21 :             HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) {
    1999         [ +  + ]:         16 :                 if (ofport->is_tunnel == true) {
    2000                 :          2 :                     dpif_ipfix_add_tunnel_port(di, &ofport->up, ofport->odp_port);
    2001                 :            :                 }
    2002                 :            :             }
    2003                 :            :         }
    2004                 :            : 
    2005         [ +  + ]:          9 :         if (!has_options) {
    2006                 :          4 :             dpif_ipfix_unref(di);
    2007                 :          4 :             ofproto->ipfix = NULL;
    2008                 :            :         }
    2009                 :            :     }
    2010                 :            : 
    2011                 :       4700 :     return 0;
    2012                 :            : }
    2013                 :            : 
    2014                 :            : static int
    2015                 :          6 : get_ipfix_stats(const struct ofproto *ofproto_,
    2016                 :            :                 bool bridge_ipfix,
    2017                 :            :                 struct ovs_list *replies)
    2018                 :            : {
    2019                 :          6 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2020                 :          6 :     struct dpif_ipfix *di = ofproto->ipfix;
    2021                 :            : 
    2022         [ +  + ]:          6 :     if (!di) {
    2023                 :          4 :         return OFPERR_NXST_NOT_CONFIGURED;
    2024                 :            :     }
    2025                 :            : 
    2026                 :          2 :     return dpif_ipfix_get_stats(di, bridge_ipfix, replies);
    2027                 :            : }
    2028                 :            : 
    2029                 :            : static int
    2030                 :      37214 : set_cfm(struct ofport *ofport_, const struct cfm_settings *s)
    2031                 :            : {
    2032                 :      37214 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2033                 :      37214 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2034                 :      37214 :     struct cfm *old = ofport->cfm;
    2035                 :      37214 :     int error = 0;
    2036                 :            : 
    2037         [ +  + ]:      37214 :     if (s) {
    2038         [ +  + ]:         32 :         if (!ofport->cfm) {
    2039                 :         16 :             ofport->cfm = cfm_create(ofport->up.netdev);
    2040                 :            :         }
    2041                 :            : 
    2042         [ +  - ]:         32 :         if (cfm_configure(ofport->cfm, s)) {
    2043                 :         32 :             error = 0;
    2044                 :         32 :             goto out;
    2045                 :            :         }
    2046                 :            : 
    2047                 :          0 :         error = EINVAL;
    2048                 :            :     }
    2049                 :      37182 :     cfm_unref(ofport->cfm);
    2050                 :      37182 :     ofport->cfm = NULL;
    2051                 :            : out:
    2052         [ +  + ]:      37214 :     if (ofport->cfm != old) {
    2053                 :         32 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2054                 :            :     }
    2055                 :      37214 :     ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
    2056                 :      37214 :                                      ofport->lldp, &ofport->up.pp.hw_addr);
    2057                 :      37214 :     return error;
    2058                 :            : }
    2059                 :            : 
    2060                 :            : static bool
    2061                 :      36468 : cfm_status_changed(struct ofport *ofport_)
    2062                 :            : {
    2063                 :      36468 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2064                 :            : 
    2065 [ +  + ][ +  + ]:      36468 :     return ofport->cfm ? cfm_check_status_change(ofport->cfm) : true;
    2066                 :            : }
    2067                 :            : 
    2068                 :            : static int
    2069                 :      36453 : get_cfm_status(const struct ofport *ofport_,
    2070                 :            :                struct cfm_status *status)
    2071                 :            : {
    2072                 :      36453 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2073                 :      36453 :     int ret = 0;
    2074                 :            : 
    2075         [ +  + ]:      36453 :     if (ofport->cfm) {
    2076                 :         72 :         cfm_get_status(ofport->cfm, status);
    2077                 :            :     } else {
    2078                 :      36381 :         ret = ENOENT;
    2079                 :            :     }
    2080                 :            : 
    2081                 :      36453 :     return ret;
    2082                 :            : }
    2083                 :            : 
    2084                 :            : static int
    2085                 :      34526 : set_bfd(struct ofport *ofport_, const struct smap *cfg)
    2086                 :            : {
    2087                 :      34526 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport_->ofproto);
    2088                 :      34526 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2089                 :            :     struct bfd *old;
    2090                 :            : 
    2091                 :      34526 :     old = ofport->bfd;
    2092                 :      34526 :     ofport->bfd = bfd_configure(old, netdev_get_name(ofport->up.netdev),
    2093                 :            :                                 cfg, ofport->up.netdev);
    2094         [ +  + ]:      34526 :     if (ofport->bfd != old) {
    2095                 :        468 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2096                 :            :     }
    2097                 :      34526 :     ofproto_dpif_monitor_port_update(ofport, ofport->bfd, ofport->cfm,
    2098                 :      34526 :                                      ofport->lldp, &ofport->up.pp.hw_addr);
    2099                 :      34526 :     return 0;
    2100                 :            : }
    2101                 :            : 
    2102                 :            : static bool
    2103                 :      36468 : bfd_status_changed(struct ofport *ofport_)
    2104                 :            : {
    2105                 :      36468 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2106                 :            : 
    2107 [ +  + ][ +  + ]:      36468 :     return ofport->bfd ? bfd_check_status_change(ofport->bfd) : true;
    2108                 :            : }
    2109                 :            : 
    2110                 :            : static int
    2111                 :      36409 : get_bfd_status(struct ofport *ofport_, struct smap *smap)
    2112                 :            : {
    2113                 :      36409 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2114                 :      36409 :     int ret = 0;
    2115                 :            : 
    2116         [ +  + ]:      36409 :     if (ofport->bfd) {
    2117                 :      20105 :         bfd_get_status(ofport->bfd, smap);
    2118                 :            :     } else {
    2119                 :      16304 :         ret = ENOENT;
    2120                 :            :     }
    2121                 :            : 
    2122                 :      36409 :     return ret;
    2123                 :            : }
    2124                 :            : 
    2125                 :            : static int
    2126                 :      34526 : set_lldp(struct ofport *ofport_,
    2127                 :            :          const struct smap *cfg)
    2128                 :            : {
    2129                 :      34526 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2130                 :      34526 :     int error = 0;
    2131                 :            : 
    2132         [ +  + ]:      34526 :     if (cfg) {
    2133         [ +  - ]:      31837 :         if (!ofport->lldp) {
    2134                 :            :             struct ofproto_dpif *ofproto;
    2135                 :            : 
    2136                 :      31837 :             ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2137                 :      31837 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2138                 :      31837 :             ofport->lldp = lldp_create(ofport->up.netdev, ofport_->mtu, cfg);
    2139                 :            :         }
    2140                 :            : 
    2141         [ -  + ]:      31837 :         if (!lldp_configure(ofport->lldp, cfg)) {
    2142                 :          0 :             error = EINVAL;
    2143                 :            :         }
    2144                 :            :     }
    2145         [ -  + ]:      34526 :     if (error) {
    2146                 :          0 :         lldp_unref(ofport->lldp);
    2147                 :          0 :         ofport->lldp = NULL;
    2148                 :            :     }
    2149                 :            : 
    2150                 :      34526 :     ofproto_dpif_monitor_port_update(ofport,
    2151                 :            :                                      ofport->bfd,
    2152                 :            :                                      ofport->cfm,
    2153                 :            :                                      ofport->lldp,
    2154                 :      34526 :                                      &ofport->up.pp.hw_addr);
    2155                 :      34526 :     return error;
    2156                 :            : }
    2157                 :            : 
    2158                 :            : static bool
    2159                 :          0 : get_lldp_status(const struct ofport *ofport_,
    2160                 :            :                struct lldp_status *status OVS_UNUSED)
    2161                 :            : {
    2162                 :          0 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2163                 :            : 
    2164                 :          0 :     return ofport->lldp ? true : false;
    2165                 :            : }
    2166                 :            : 
    2167                 :            : static int
    2168                 :       4700 : set_aa(struct ofproto *ofproto OVS_UNUSED,
    2169                 :            :        const struct aa_settings *s)
    2170                 :            : {
    2171                 :       4700 :     return aa_configure(s);
    2172                 :            : }
    2173                 :            : 
    2174                 :            : static int
    2175                 :          0 : aa_mapping_set(struct ofproto *ofproto_ OVS_UNUSED, void *aux,
    2176                 :            :                const struct aa_mapping_settings *s)
    2177                 :            : {
    2178                 :          0 :     return aa_mapping_register(aux, s);
    2179                 :            : }
    2180                 :            : 
    2181                 :            : static int
    2182                 :          0 : aa_mapping_unset(struct ofproto *ofproto OVS_UNUSED, void *aux)
    2183                 :            : {
    2184                 :          0 :     return aa_mapping_unregister(aux);
    2185                 :            : }
    2186                 :            : 
    2187                 :            : static int
    2188                 :          0 : aa_vlan_get_queued(struct ofproto *ofproto OVS_UNUSED, struct ovs_list *list)
    2189                 :            : {
    2190                 :          0 :     return aa_get_vlan_queued(list);
    2191                 :            : }
    2192                 :            : 
    2193                 :            : static unsigned int
    2194                 :       5132 : aa_vlan_get_queue_size(struct ofproto *ofproto OVS_UNUSED)
    2195                 :            : {
    2196                 :       5132 :     return aa_get_vlan_queue_size();
    2197                 :            : }
    2198                 :            : 
    2199                 :            : 
    2200                 :            : /* Spanning Tree. */
    2201                 :            : 
    2202                 :            : /* Called while rstp_mutex is held. */
    2203                 :            : static void
    2204                 :          7 : rstp_send_bpdu_cb(struct dp_packet *pkt, void *ofport_, void *ofproto_)
    2205                 :            : {
    2206                 :          7 :     struct ofproto_dpif *ofproto = ofproto_;
    2207                 :          7 :     struct ofport_dpif *ofport = ofport_;
    2208                 :          7 :     struct eth_header *eth = dp_packet_l2(pkt);
    2209                 :            : 
    2210                 :          7 :     netdev_get_etheraddr(ofport->up.netdev, &eth->eth_src);
    2211         [ -  + ]:          7 :     if (eth_addr_is_zero(eth->eth_src)) {
    2212         [ #  # ]:          0 :         VLOG_WARN_RL(&rl, "%s port %d: cannot send RSTP BPDU on a port which "
    2213                 :            :                      "does not have a configured source MAC address.",
    2214                 :            :                      ofproto->up.name, ofp_to_u16(ofport->up.ofp_port));
    2215                 :            :     } else {
    2216                 :          7 :         ofproto_dpif_send_packet(ofport, false, pkt);
    2217                 :            :     }
    2218                 :          7 :     dp_packet_delete(pkt);
    2219                 :          7 : }
    2220                 :            : 
    2221                 :            : static void
    2222                 :         13 : send_bpdu_cb(struct dp_packet *pkt, int port_num, void *ofproto_)
    2223                 :            : {
    2224                 :         13 :     struct ofproto_dpif *ofproto = ofproto_;
    2225                 :         13 :     struct stp_port *sp = stp_get_port(ofproto->stp, port_num);
    2226                 :            :     struct ofport_dpif *ofport;
    2227                 :            : 
    2228                 :         13 :     ofport = stp_port_get_aux(sp);
    2229         [ -  + ]:         13 :     if (!ofport) {
    2230         [ #  # ]:          0 :         VLOG_WARN_RL(&rl, "%s: cannot send BPDU on unknown port %d",
    2231                 :            :                      ofproto->up.name, port_num);
    2232                 :            :     } else {
    2233                 :         13 :         struct eth_header *eth = dp_packet_l2(pkt);
    2234                 :            : 
    2235                 :         13 :         netdev_get_etheraddr(ofport->up.netdev, &eth->eth_src);
    2236         [ -  + ]:         13 :         if (eth_addr_is_zero(eth->eth_src)) {
    2237         [ #  # ]:          0 :             VLOG_WARN_RL(&rl, "%s: cannot send BPDU on port %d "
    2238                 :            :                          "with unknown MAC", ofproto->up.name, port_num);
    2239                 :            :         } else {
    2240                 :         13 :             ofproto_dpif_send_packet(ofport, false, pkt);
    2241                 :            :         }
    2242                 :            :     }
    2243                 :         13 :     dp_packet_delete(pkt);
    2244                 :         13 : }
    2245                 :            : 
    2246                 :            : /* Configure RSTP on 'ofproto_' using the settings defined in 's'. */
    2247                 :            : static void
    2248                 :       4700 : set_rstp(struct ofproto *ofproto_, const struct ofproto_rstp_settings *s)
    2249                 :            : {
    2250                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2251                 :            : 
    2252                 :            :     /* Only revalidate flows if the configuration changed. */
    2253         [ +  + ]:       4700 :     if (!s != !ofproto->rstp) {
    2254                 :          2 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2255                 :            :     }
    2256                 :            : 
    2257         [ +  + ]:       4700 :     if (s) {
    2258         [ +  + ]:         12 :         if (!ofproto->rstp) {
    2259                 :          2 :             ofproto->rstp = rstp_create(ofproto_->name, s->address,
    2260                 :            :                                         rstp_send_bpdu_cb, ofproto);
    2261                 :          2 :             ofproto->rstp_last_tick = time_msec();
    2262                 :            :         }
    2263                 :         12 :         rstp_set_bridge_address(ofproto->rstp, s->address);
    2264                 :         12 :         rstp_set_bridge_priority(ofproto->rstp, s->priority);
    2265                 :         12 :         rstp_set_bridge_ageing_time(ofproto->rstp, s->ageing_time);
    2266                 :         12 :         rstp_set_bridge_force_protocol_version(ofproto->rstp,
    2267                 :            :                                                s->force_protocol_version);
    2268                 :         12 :         rstp_set_bridge_max_age(ofproto->rstp, s->bridge_max_age);
    2269                 :         12 :         rstp_set_bridge_forward_delay(ofproto->rstp, s->bridge_forward_delay);
    2270                 :         12 :         rstp_set_bridge_transmit_hold_count(ofproto->rstp,
    2271                 :         12 :                                             s->transmit_hold_count);
    2272                 :            :     } else {
    2273                 :            :         struct ofport *ofport;
    2274 [ +  + ][ -  + ]:      36575 :         HMAP_FOR_EACH (ofport, hmap_node, &ofproto->up.ports) {
    2275                 :      31887 :             set_rstp_port(ofport, NULL);
    2276                 :            :         }
    2277                 :       4688 :         rstp_unref(ofproto->rstp);
    2278                 :       4688 :         ofproto->rstp = NULL;
    2279                 :            :     }
    2280                 :       4700 : }
    2281                 :            : 
    2282                 :            : static void
    2283                 :       6579 : get_rstp_status(struct ofproto *ofproto_, struct ofproto_rstp_status *s)
    2284                 :            : {
    2285                 :       6579 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2286                 :            : 
    2287         [ +  + ]:       6579 :     if (ofproto->rstp) {
    2288                 :         25 :         s->enabled = true;
    2289                 :         25 :         s->root_id = rstp_get_root_id(ofproto->rstp);
    2290                 :         25 :         s->bridge_id = rstp_get_bridge_id(ofproto->rstp);
    2291                 :         25 :         s->designated_id = rstp_get_designated_id(ofproto->rstp);
    2292                 :         25 :         s->root_path_cost = rstp_get_root_path_cost(ofproto->rstp);
    2293                 :         25 :         s->designated_port_id = rstp_get_designated_port_id(ofproto->rstp);
    2294                 :         25 :         s->bridge_port_id = rstp_get_bridge_port_id(ofproto->rstp);
    2295                 :            :     } else {
    2296                 :       6554 :         s->enabled = false;
    2297                 :            :     }
    2298                 :       6579 : }
    2299                 :            : 
    2300                 :            : static void
    2301                 :         15 : update_rstp_port_state(struct ofport_dpif *ofport)
    2302                 :            : {
    2303                 :         15 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2304                 :            :     enum rstp_state state;
    2305                 :            : 
    2306                 :            :     /* Figure out new state. */
    2307         [ +  + ]:         15 :     state = ofport->rstp_port ? rstp_port_get_state(ofport->rstp_port)
    2308                 :            :         : RSTP_DISABLED;
    2309                 :            : 
    2310                 :            :     /* Update state. */
    2311         [ +  + ]:         15 :     if (ofport->rstp_state != state) {
    2312                 :            :         enum ofputil_port_state of_state;
    2313                 :            :         bool fwd_change;
    2314                 :            : 
    2315         [ +  - ]:          6 :         VLOG_DBG("port %s: RSTP state changed from %s to %s",
    2316                 :            :                  netdev_get_name(ofport->up.netdev),
    2317                 :            :                  rstp_state_name(ofport->rstp_state),
    2318                 :            :                  rstp_state_name(state));
    2319                 :            : 
    2320         [ +  + ]:         12 :         if (rstp_learn_in_state(ofport->rstp_state)
    2321                 :          6 :             != rstp_learn_in_state(state)) {
    2322                 :            :             /* XXX: Learning action flows should also be flushed. */
    2323         [ +  + ]:          4 :             if (ofport->bundle) {
    2324         [ -  + ]:          2 :                 if (!rstp_shift_root_learned_address(ofproto->rstp)
    2325         [ #  # ]:          0 :                     || rstp_get_old_root_aux(ofproto->rstp) != ofport) {
    2326                 :          2 :                     bundle_flush_macs(ofport->bundle, false);
    2327                 :            :                 }
    2328                 :            :             }
    2329                 :            :         }
    2330                 :          6 :         fwd_change = rstp_forward_in_state(ofport->rstp_state)
    2331                 :          6 :             != rstp_forward_in_state(state);
    2332                 :            : 
    2333                 :          6 :         ofproto->backer->need_revalidate = REV_RSTP;
    2334                 :          6 :         ofport->rstp_state = state;
    2335                 :            : 
    2336 [ +  + ][ +  + ]:          6 :         if (fwd_change && ofport->bundle) {
    2337                 :          2 :             bundle_update(ofport->bundle);
    2338                 :            :         }
    2339                 :            : 
    2340                 :            :         /* Update the RSTP state bits in the OpenFlow port description. */
    2341                 :          6 :         of_state = ofport->up.pp.state & ~OFPUTIL_PS_STP_MASK;
    2342 [ +  - ][ +  + ]:          6 :         of_state |= (state == RSTP_LEARNING ? OFPUTIL_PS_STP_LEARN
    2343                 :            :                 : state == RSTP_FORWARDING ? OFPUTIL_PS_STP_FORWARD
    2344                 :            :                 : state == RSTP_DISCARDING ?  OFPUTIL_PS_STP_LISTEN
    2345                 :            :                 : 0);
    2346                 :          6 :         ofproto_port_set_state(&ofport->up, of_state);
    2347                 :            :     }
    2348                 :         15 : }
    2349                 :            : 
    2350                 :            : static void
    2351                 :     157605 : rstp_run(struct ofproto_dpif *ofproto)
    2352                 :            : {
    2353         [ +  + ]:     157605 :     if (ofproto->rstp) {
    2354                 :        186 :         long long int now = time_msec();
    2355                 :        186 :         long long int elapsed = now - ofproto->rstp_last_tick;
    2356                 :            :         struct rstp_port *rp;
    2357                 :            :         struct ofport_dpif *ofport;
    2358                 :            : 
    2359                 :            :         /* Every second, decrease the values of the timers. */
    2360         [ +  + ]:        186 :         if (elapsed >= 1000) {
    2361                 :          4 :             rstp_tick_timers(ofproto->rstp);
    2362                 :          4 :             ofproto->rstp_last_tick = now;
    2363                 :            :         }
    2364                 :        186 :         rp = NULL;
    2365         [ +  + ]:        190 :         while ((ofport = rstp_get_next_changed_port_aux(ofproto->rstp, &rp))) {
    2366                 :          4 :             update_rstp_port_state(ofport);
    2367                 :            :         }
    2368                 :        186 :         rp = NULL;
    2369                 :        186 :         ofport = NULL;
    2370                 :            :         /* FIXME: This check should be done on-event (i.e., when setting
    2371                 :            :          * p->fdb_flush) and not periodically.
    2372                 :            :          */
    2373         [ +  + ]:        188 :         while ((ofport = rstp_check_and_reset_fdb_flush(ofproto->rstp, &rp))) {
    2374         [ -  + ]:          2 :             if (!rstp_shift_root_learned_address(ofproto->rstp)
    2375         [ #  # ]:          0 :                 || rstp_get_old_root_aux(ofproto->rstp) != ofport) {
    2376                 :          2 :                 bundle_flush_macs(ofport->bundle, false);
    2377                 :            :             }
    2378                 :            :         }
    2379                 :            : 
    2380         [ -  + ]:        186 :         if (rstp_shift_root_learned_address(ofproto->rstp)) {
    2381                 :          0 :             struct ofport_dpif *old_root_aux =
    2382                 :          0 :                 (struct ofport_dpif *)rstp_get_old_root_aux(ofproto->rstp);
    2383                 :          0 :             struct ofport_dpif *new_root_aux =
    2384                 :          0 :                 (struct ofport_dpif *)rstp_get_new_root_aux(ofproto->rstp);
    2385 [ #  # ][ #  # ]:          0 :             if (old_root_aux != NULL && new_root_aux != NULL) {
    2386                 :          0 :                 bundle_move(old_root_aux->bundle, new_root_aux->bundle);
    2387                 :        186 :                 rstp_reset_root_changed(ofproto->rstp);
    2388                 :            :             }
    2389                 :            :         }
    2390                 :            :     }
    2391                 :     157605 : }
    2392                 :            : 
    2393                 :            : /* Configures STP on 'ofproto_' using the settings defined in 's'. */
    2394                 :            : static int
    2395                 :       4700 : set_stp(struct ofproto *ofproto_, const struct ofproto_stp_settings *s)
    2396                 :            : {
    2397                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2398                 :            : 
    2399                 :            :     /* Only revalidate flows if the configuration changed. */
    2400         [ +  + ]:       4700 :     if (!s != !ofproto->stp) {
    2401                 :          2 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2402                 :            :     }
    2403                 :            : 
    2404         [ +  + ]:       4700 :     if (s) {
    2405         [ +  + ]:         10 :         if (!ofproto->stp) {
    2406                 :          2 :             ofproto->stp = stp_create(ofproto_->name, s->system_id,
    2407                 :            :                                       send_bpdu_cb, ofproto);
    2408                 :          2 :             ofproto->stp_last_tick = time_msec();
    2409                 :            :         }
    2410                 :            : 
    2411                 :         10 :         stp_set_bridge_id(ofproto->stp, s->system_id);
    2412                 :         10 :         stp_set_bridge_priority(ofproto->stp, s->priority);
    2413                 :         10 :         stp_set_hello_time(ofproto->stp, s->hello_time);
    2414                 :         10 :         stp_set_max_age(ofproto->stp, s->max_age);
    2415                 :         10 :         stp_set_forward_delay(ofproto->stp, s->fwd_delay);
    2416                 :            :     }  else {
    2417                 :            :         struct ofport *ofport;
    2418                 :            : 
    2419 [ +  + ][ -  + ]:      36587 :         HMAP_FOR_EACH (ofport, hmap_node, &ofproto->up.ports) {
    2420                 :      31897 :             set_stp_port(ofport, NULL);
    2421                 :            :         }
    2422                 :            : 
    2423                 :       4690 :         stp_unref(ofproto->stp);
    2424                 :       4690 :         ofproto->stp = NULL;
    2425                 :            :     }
    2426                 :            : 
    2427                 :       4700 :     return 0;
    2428                 :            : }
    2429                 :            : 
    2430                 :            : static int
    2431                 :       6579 : get_stp_status(struct ofproto *ofproto_, struct ofproto_stp_status *s)
    2432                 :            : {
    2433                 :       6579 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2434                 :            : 
    2435         [ +  + ]:       6579 :     if (ofproto->stp) {
    2436                 :         38 :         s->enabled = true;
    2437                 :         38 :         s->bridge_id = stp_get_bridge_id(ofproto->stp);
    2438                 :         38 :         s->designated_root = stp_get_designated_root(ofproto->stp);
    2439                 :         38 :         s->root_path_cost = stp_get_root_path_cost(ofproto->stp);
    2440                 :            :     } else {
    2441                 :       6541 :         s->enabled = false;
    2442                 :            :     }
    2443                 :            : 
    2444                 :       6579 :     return 0;
    2445                 :            : }
    2446                 :            : 
    2447                 :            : static void
    2448                 :         14 : update_stp_port_state(struct ofport_dpif *ofport)
    2449                 :            : {
    2450                 :         14 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2451                 :            :     enum stp_state state;
    2452                 :            : 
    2453                 :            :     /* Figure out new state. */
    2454         [ +  + ]:         14 :     state = ofport->stp_port ? stp_port_get_state(ofport->stp_port)
    2455                 :            :                              : STP_DISABLED;
    2456                 :            : 
    2457                 :            :     /* Update state. */
    2458         [ +  + ]:         14 :     if (ofport->stp_state != state) {
    2459                 :            :         enum ofputil_port_state of_state;
    2460                 :            :         bool fwd_change;
    2461                 :            : 
    2462         [ +  - ]:          8 :         VLOG_DBG("port %s: STP state changed from %s to %s",
    2463                 :            :                  netdev_get_name(ofport->up.netdev),
    2464                 :            :                  stp_state_name(ofport->stp_state),
    2465                 :            :                  stp_state_name(state));
    2466         [ +  + ]:         16 :         if (stp_learn_in_state(ofport->stp_state)
    2467                 :          8 :                 != stp_learn_in_state(state)) {
    2468                 :            :             /* xxx Learning action flows should also be flushed. */
    2469                 :          4 :             ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    2470                 :          4 :             mac_learning_flush(ofproto->ml);
    2471                 :          4 :             ovs_rwlock_unlock(&ofproto->ml->rwlock);
    2472                 :          4 :             mcast_snooping_mdb_flush(ofproto->ms);
    2473                 :            :         }
    2474                 :          8 :         fwd_change = stp_forward_in_state(ofport->stp_state)
    2475                 :          8 :                         != stp_forward_in_state(state);
    2476                 :            : 
    2477                 :          8 :         ofproto->backer->need_revalidate = REV_STP;
    2478                 :          8 :         ofport->stp_state = state;
    2479                 :          8 :         ofport->stp_state_entered = time_msec();
    2480                 :            : 
    2481 [ +  + ][ +  + ]:          8 :         if (fwd_change && ofport->bundle) {
    2482                 :          2 :             bundle_update(ofport->bundle);
    2483                 :            :         }
    2484                 :            : 
    2485                 :            :         /* Update the STP state bits in the OpenFlow port description. */
    2486                 :          8 :         of_state = ofport->up.pp.state & ~OFPUTIL_PS_STP_MASK;
    2487 [ +  + ][ +  + ]:          8 :         of_state |= (state == STP_LISTENING ? OFPUTIL_PS_STP_LISTEN
         [ +  + ][ -  + ]
    2488                 :            :                      : state == STP_LEARNING ? OFPUTIL_PS_STP_LEARN
    2489                 :            :                      : state == STP_FORWARDING ? OFPUTIL_PS_STP_FORWARD
    2490                 :            :                      : state == STP_BLOCKING ?  OFPUTIL_PS_STP_BLOCK
    2491                 :            :                      : 0);
    2492                 :          8 :         ofproto_port_set_state(&ofport->up, of_state);
    2493                 :            :     }
    2494                 :         14 : }
    2495                 :            : 
    2496                 :            : /* Configures STP on 'ofport_' using the settings defined in 's'.  The
    2497                 :            :  * caller is responsible for assigning STP port numbers and ensuring
    2498                 :            :  * there are no duplicates. */
    2499                 :            : static int
    2500                 :      34605 : set_stp_port(struct ofport *ofport_,
    2501                 :            :              const struct ofproto_port_stp_settings *s)
    2502                 :            : {
    2503                 :      34605 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2504                 :      34605 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2505                 :      34605 :     struct stp_port *sp = ofport->stp_port;
    2506                 :            : 
    2507 [ +  + ][ +  + ]:      34605 :     if (!s || !s->enable) {
    2508         [ +  + ]:      34599 :         if (sp) {
    2509                 :          2 :             ofport->stp_port = NULL;
    2510                 :          2 :             stp_port_disable(sp);
    2511                 :          2 :             update_stp_port_state(ofport);
    2512                 :            :         }
    2513                 :      34599 :         return 0;
    2514 [ +  + ][ -  + ]:          6 :     } else if (sp && stp_port_no(sp) != s->port_num
    2515         [ #  # ]:          0 :                && ofport == stp_port_get_aux(sp)) {
    2516                 :            :         /* The port-id changed, so disable the old one if it's not
    2517                 :            :          * already in use by another port. */
    2518                 :          0 :         stp_port_disable(sp);
    2519                 :            :     }
    2520                 :            : 
    2521                 :          6 :     sp = ofport->stp_port = stp_get_port(ofproto->stp, s->port_num);
    2522                 :            : 
    2523                 :            :     /* Set name before enabling the port so that debugging messages can print
    2524                 :            :      * the name. */
    2525                 :          6 :     stp_port_set_name(sp, netdev_get_name(ofport->up.netdev));
    2526                 :          6 :     stp_port_enable(sp);
    2527                 :            : 
    2528                 :          6 :     stp_port_set_aux(sp, ofport);
    2529                 :          6 :     stp_port_set_priority(sp, s->priority);
    2530                 :          6 :     stp_port_set_path_cost(sp, s->path_cost);
    2531                 :            : 
    2532                 :          6 :     update_stp_port_state(ofport);
    2533                 :            : 
    2534                 :          6 :     return 0;
    2535                 :            : }
    2536                 :            : 
    2537                 :            : static int
    2538                 :      36256 : get_stp_port_status(struct ofport *ofport_,
    2539                 :            :                     struct ofproto_port_stp_status *s)
    2540                 :            : {
    2541                 :      36256 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2542                 :      36256 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2543                 :      36256 :     struct stp_port *sp = ofport->stp_port;
    2544                 :            : 
    2545 [ +  + ][ +  + ]:      36256 :     if (!ofproto->stp || !sp) {
    2546                 :      36222 :         s->enabled = false;
    2547                 :      36222 :         return 0;
    2548                 :            :     }
    2549                 :            : 
    2550                 :         34 :     s->enabled = true;
    2551                 :         34 :     s->port_id = stp_port_get_id(sp);
    2552                 :         34 :     s->state = stp_port_get_state(sp);
    2553                 :         34 :     s->sec_in_state = (time_msec() - ofport->stp_state_entered) / 1000;
    2554                 :         34 :     s->role = stp_port_get_role(sp);
    2555                 :            : 
    2556                 :         34 :     return 0;
    2557                 :            : }
    2558                 :            : 
    2559                 :            : static int
    2560                 :       5240 : get_stp_port_stats(struct ofport *ofport_,
    2561                 :            :                    struct ofproto_port_stp_stats *s)
    2562                 :            : {
    2563                 :       5240 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2564                 :       5240 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2565                 :       5240 :     struct stp_port *sp = ofport->stp_port;
    2566                 :            : 
    2567 [ +  + ][ +  + ]:       5240 :     if (!ofproto->stp || !sp) {
    2568                 :       5230 :         s->enabled = false;
    2569                 :       5230 :         return 0;
    2570                 :            :     }
    2571                 :            : 
    2572                 :         10 :     s->enabled = true;
    2573                 :         10 :     stp_port_get_counts(sp, &s->tx_count, &s->rx_count, &s->error_count);
    2574                 :            : 
    2575                 :         10 :     return 0;
    2576                 :            : }
    2577                 :            : 
    2578                 :            : static void
    2579                 :     157605 : stp_run(struct ofproto_dpif *ofproto)
    2580                 :            : {
    2581         [ +  + ]:     157605 :     if (ofproto->stp) {
    2582                 :        244 :         long long int now = time_msec();
    2583                 :        244 :         long long int elapsed = now - ofproto->stp_last_tick;
    2584                 :            :         struct stp_port *sp;
    2585                 :            : 
    2586         [ +  + ]:        244 :         if (elapsed > 0) {
    2587                 :         62 :             stp_tick(ofproto->stp, MIN(INT_MAX, elapsed));
    2588                 :         62 :             ofproto->stp_last_tick = now;
    2589                 :            :         }
    2590         [ +  + ]:        250 :         while (stp_get_changed_port(ofproto->stp, &sp)) {
    2591                 :          6 :             struct ofport_dpif *ofport = stp_port_get_aux(sp);
    2592                 :            : 
    2593         [ +  - ]:          6 :             if (ofport) {
    2594                 :          6 :                 update_stp_port_state(ofport);
    2595                 :            :             }
    2596                 :            :         }
    2597                 :            : 
    2598         [ +  + ]:        244 :         if (stp_check_and_reset_fdb_flush(ofproto->stp)) {
    2599                 :          3 :             ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    2600                 :          3 :             mac_learning_flush(ofproto->ml);
    2601                 :          3 :             ovs_rwlock_unlock(&ofproto->ml->rwlock);
    2602                 :        244 :             mcast_snooping_mdb_flush(ofproto->ms);
    2603                 :            :         }
    2604                 :            :     }
    2605                 :     157605 : }
    2606                 :            : 
    2607                 :            : static void
    2608                 :     153567 : stp_wait(struct ofproto_dpif *ofproto)
    2609                 :            : {
    2610         [ +  + ]:     153567 :     if (ofproto->stp) {
    2611                 :        236 :         poll_timer_wait(1000);
    2612                 :            :     }
    2613                 :     153567 : }
    2614                 :            : 
    2615                 :            : /* Configures RSTP on 'ofport_' using the settings defined in 's'.  The
    2616                 :            :  * caller is responsible for assigning RSTP port numbers and ensuring
    2617                 :            :  * there are no duplicates. */
    2618                 :            : static void
    2619                 :      37294 : set_rstp_port(struct ofport *ofport_,
    2620                 :            :               const struct ofproto_port_rstp_settings *s)
    2621                 :            : {
    2622                 :      37294 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2623                 :      37294 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2624                 :      37294 :     struct rstp_port *rp = ofport->rstp_port;
    2625                 :            : 
    2626 [ +  + ][ +  + ]:      37294 :     if (!s || !s->enable) {
    2627         [ +  + ]:      37285 :         if (rp) {
    2628                 :          2 :             rstp_port_set_aux(rp, NULL);
    2629                 :          2 :             rstp_port_set_state(rp, RSTP_DISABLED);
    2630                 :          2 :             rstp_port_set_mac_operational(rp, false);
    2631                 :          2 :             ofport->rstp_port = NULL;
    2632                 :          2 :             rstp_port_unref(rp);
    2633                 :          2 :             update_rstp_port_state(ofport);
    2634                 :            :         }
    2635                 :      37285 :         return;
    2636                 :            :     }
    2637                 :            : 
    2638                 :            :     /* Check if need to add a new port. */
    2639         [ +  + ]:          9 :     if (!rp) {
    2640                 :          2 :         rp = ofport->rstp_port = rstp_add_port(ofproto->rstp);
    2641                 :            :     }
    2642                 :            : 
    2643                 :          9 :     rstp_port_set(rp, s->port_num, s->priority, s->path_cost,
    2644                 :         18 :                   s->admin_edge_port, s->auto_edge,
    2645                 :         27 :                   s->admin_p2p_mac_state, s->admin_port_state, s->mcheck,
    2646                 :            :                   ofport);
    2647                 :          9 :     update_rstp_port_state(ofport);
    2648                 :            :     /* Synchronize operational status. */
    2649                 :          9 :     rstp_port_set_mac_operational(rp, ofport->may_enable);
    2650                 :            : }
    2651                 :            : 
    2652                 :            : static void
    2653                 :      36256 : get_rstp_port_status(struct ofport *ofport_,
    2654                 :            :         struct ofproto_port_rstp_status *s)
    2655                 :            : {
    2656                 :      36256 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2657                 :      36256 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2658                 :      36256 :     struct rstp_port *rp = ofport->rstp_port;
    2659                 :            : 
    2660 [ +  + ][ +  + ]:      36256 :     if (!ofproto->rstp || !rp) {
    2661                 :      36234 :         s->enabled = false;
    2662                 :      36234 :         return;
    2663                 :            :     }
    2664                 :            : 
    2665                 :         22 :     s->enabled = true;
    2666                 :         22 :     rstp_port_get_status(rp, &s->port_id, &s->state, &s->role,
    2667                 :            :                          &s->designated_bridge_id, &s->designated_port_id,
    2668                 :            :                          &s->designated_path_cost, &s->tx_count,
    2669                 :            :                          &s->rx_count, &s->error_count, &s->uptime);
    2670                 :            : }
    2671                 :            : 
    2672                 :            : 
    2673                 :            : static int
    2674                 :      31837 : set_queues(struct ofport *ofport_, const struct ofproto_port_queue *qdscp,
    2675                 :            :            size_t n_qdscp)
    2676                 :            : {
    2677                 :      31837 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    2678                 :      31837 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    2679                 :            : 
    2680         [ +  + ]:      31837 :     if (ofport->n_qdscp != n_qdscp
    2681 [ -  + ][ #  # ]:      31836 :         || (n_qdscp && memcmp(ofport->qdscp, qdscp,
    2682                 :            :                               n_qdscp * sizeof *qdscp))) {
    2683                 :          1 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2684                 :          1 :         free(ofport->qdscp);
    2685                 :          1 :         ofport->qdscp = n_qdscp
    2686                 :          1 :             ? xmemdup(qdscp, n_qdscp * sizeof *qdscp)
    2687         [ +  - ]:          1 :             : NULL;
    2688                 :          1 :         ofport->n_qdscp = n_qdscp;
    2689                 :            :     }
    2690                 :            : 
    2691                 :      31837 :     return 0;
    2692                 :            : }
    2693                 :            : 
    2694                 :            : /* Bundles. */
    2695                 :            : 
    2696                 :            : /* Expires all MAC learning entries associated with 'bundle' and forces its
    2697                 :            :  * ofproto to revalidate every flow.
    2698                 :            :  *
    2699                 :            :  * Normally MAC learning entries are removed only from the ofproto associated
    2700                 :            :  * with 'bundle', but if 'all_ofprotos' is true, then the MAC learning entries
    2701                 :            :  * are removed from every ofproto.  When patch ports and SLB bonds are in use
    2702                 :            :  * and a VM migration happens and the gratuitous ARPs are somehow lost, this
    2703                 :            :  * avoids a MAC_ENTRY_IDLE_TIME delay before the migrated VM can communicate
    2704                 :            :  * with the host from which it migrated. */
    2705                 :            : static void
    2706                 :       2687 : bundle_flush_macs(struct ofbundle *bundle, bool all_ofprotos)
    2707                 :            : {
    2708                 :       2687 :     struct ofproto_dpif *ofproto = bundle->ofproto;
    2709                 :       2687 :     struct mac_learning *ml = ofproto->ml;
    2710                 :            :     struct mac_entry *mac, *next_mac;
    2711                 :            : 
    2712                 :       2687 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2713                 :       2687 :     ovs_rwlock_wrlock(&ml->rwlock);
    2714 [ +  + ][ +  + ]:       3865 :     LIST_FOR_EACH_SAFE (mac, next_mac, lru_node, &ml->lrus) {
    2715         [ +  + ]:       1178 :         if (mac_entry_get_port(ml, mac) == bundle) {
    2716         [ +  - ]:        508 :             if (all_ofprotos) {
    2717                 :            :                 struct ofproto_dpif *o;
    2718                 :            : 
    2719 [ +  + ][ -  + ]:       1217 :                 HMAP_FOR_EACH (o, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
    2720         [ +  + ]:        709 :                     if (o != ofproto) {
    2721                 :            :                         struct mac_entry *e;
    2722                 :            : 
    2723                 :        201 :                         ovs_rwlock_wrlock(&o->ml->rwlock);
    2724                 :        201 :                         e = mac_learning_lookup(o->ml, mac->mac, mac->vlan);
    2725         [ +  + ]:        201 :                         if (e) {
    2726                 :        117 :                             mac_learning_expire(o->ml, e);
    2727                 :            :                         }
    2728                 :        201 :                         ovs_rwlock_unlock(&o->ml->rwlock);
    2729                 :            :                     }
    2730                 :            :                 }
    2731                 :            :             }
    2732                 :            : 
    2733                 :        508 :             mac_learning_expire(ml, mac);
    2734                 :            :         }
    2735                 :            :     }
    2736                 :       2687 :     ovs_rwlock_unlock(&ml->rwlock);
    2737                 :       2687 : }
    2738                 :            : 
    2739                 :            : static void
    2740                 :          0 : bundle_move(struct ofbundle *old, struct ofbundle *new)
    2741                 :            : {
    2742                 :          0 :     struct ofproto_dpif *ofproto = old->ofproto;
    2743                 :          0 :     struct mac_learning *ml = ofproto->ml;
    2744                 :            :     struct mac_entry *mac, *next_mac;
    2745                 :            : 
    2746         [ #  # ]:          0 :     ovs_assert(new->ofproto == old->ofproto);
    2747                 :            : 
    2748                 :          0 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2749                 :          0 :     ovs_rwlock_wrlock(&ml->rwlock);
    2750 [ #  # ][ #  # ]:          0 :     LIST_FOR_EACH_SAFE (mac, next_mac, lru_node, &ml->lrus) {
    2751         [ #  # ]:          0 :         if (mac_entry_get_port(ml, mac) == old) {
    2752                 :          0 :             mac_entry_set_port(ml, mac, new);
    2753                 :            :         }
    2754                 :            :     }
    2755                 :          0 :     ovs_rwlock_unlock(&ml->rwlock);
    2756                 :          0 : }
    2757                 :            : 
    2758                 :            : static struct ofbundle *
    2759                 :      34643 : bundle_lookup(const struct ofproto_dpif *ofproto, void *aux)
    2760                 :            : {
    2761                 :            :     struct ofbundle *bundle;
    2762                 :            : 
    2763 [ +  + ][ -  + ]:      56565 :     HMAP_FOR_EACH_IN_BUCKET (bundle, hmap_node, hash_pointer(aux, 0),
    2764                 :            :                              &ofproto->bundles) {
    2765         [ +  + ]:      53624 :         if (bundle->aux == aux) {
    2766                 :      31702 :             return bundle;
    2767                 :            :         }
    2768                 :            :     }
    2769                 :       2941 :     return NULL;
    2770                 :            : }
    2771                 :            : 
    2772                 :            : static void
    2773                 :       2696 : bundle_update(struct ofbundle *bundle)
    2774                 :            : {
    2775                 :            :     struct ofport_dpif *port;
    2776                 :            : 
    2777                 :       2696 :     bundle->floodable = true;
    2778         [ +  + ]:       2726 :     LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
    2779         [ +  + ]:         32 :         if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD
    2780         [ +  - ]:         30 :             || port->is_layer3
    2781 [ +  + ][ +  - ]:         30 :             || (bundle->ofproto->stp && !stp_forward_in_state(port->stp_state))
    2782 [ +  + ][ -  + ]:         30 :             || (bundle->ofproto->rstp && !rstp_forward_in_state(port->rstp_state))) {
    2783                 :          2 :             bundle->floodable = false;
    2784                 :          2 :             break;
    2785                 :            :         }
    2786                 :            :     }
    2787                 :       2696 : }
    2788                 :            : 
    2789                 :            : static void
    2790                 :       2689 : bundle_del_port(struct ofport_dpif *port)
    2791                 :            : {
    2792                 :       2689 :     struct ofbundle *bundle = port->bundle;
    2793                 :            : 
    2794                 :       2689 :     bundle->ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2795                 :            : 
    2796                 :       2689 :     ovs_list_remove(&port->bundle_node);
    2797                 :       2689 :     port->bundle = NULL;
    2798                 :            : 
    2799         [ +  + ]:       2689 :     if (bundle->lacp) {
    2800                 :         27 :         lacp_slave_unregister(bundle->lacp, port);
    2801                 :            :     }
    2802         [ +  + ]:       2689 :     if (bundle->bond) {
    2803                 :         41 :         bond_slave_unregister(bundle->bond, port);
    2804                 :            :     }
    2805                 :            : 
    2806                 :       2689 :     bundle_update(bundle);
    2807                 :       2689 : }
    2808                 :            : 
    2809                 :            : static bool
    2810                 :      31837 : bundle_add_port(struct ofbundle *bundle, ofp_port_t ofp_port,
    2811                 :            :                 struct lacp_slave_settings *lacp)
    2812                 :            : {
    2813                 :            :     struct ofport_dpif *port;
    2814                 :            : 
    2815                 :      31837 :     port = ofp_port_to_ofport(bundle->ofproto, ofp_port);
    2816         [ -  + ]:      31837 :     if (!port) {
    2817                 :          0 :         return false;
    2818                 :            :     }
    2819                 :            : 
    2820         [ +  + ]:      31837 :     if (port->bundle != bundle) {
    2821                 :       2689 :         bundle->ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2822         [ -  + ]:       2689 :         if (port->bundle) {
    2823                 :          0 :             bundle_remove(&port->up);
    2824                 :            :         }
    2825                 :            : 
    2826                 :       2689 :         port->bundle = bundle;
    2827                 :       2689 :         ovs_list_push_back(&bundle->ports, &port->bundle_node);
    2828         [ +  - ]:       2689 :         if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD
    2829         [ +  + ]:       2689 :             || port->is_layer3
    2830 [ +  + ][ -  + ]:       2687 :             || (bundle->ofproto->stp && !stp_forward_in_state(port->stp_state))
    2831 [ +  + ][ +  - ]:       2683 :             || (bundle->ofproto->rstp && !rstp_forward_in_state(port->rstp_state))) {
    2832                 :          8 :             bundle->floodable = false;
    2833                 :            :         }
    2834                 :            :     }
    2835         [ +  + ]:      31837 :     if (lacp) {
    2836                 :         41 :         bundle->ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2837                 :         41 :         lacp_slave_register(bundle->lacp, port, lacp);
    2838                 :            :     }
    2839                 :            : 
    2840                 :      31837 :     return true;
    2841                 :            : }
    2842                 :            : 
    2843                 :            : static void
    2844                 :       2935 : bundle_destroy(struct ofbundle *bundle)
    2845                 :            : {
    2846                 :            :     struct ofproto_dpif *ofproto;
    2847                 :            :     struct ofport_dpif *port, *next_port;
    2848                 :            : 
    2849         [ +  + ]:       2935 :     if (!bundle) {
    2850                 :        268 :         return;
    2851                 :            :     }
    2852                 :            : 
    2853                 :       2667 :     ofproto = bundle->ofproto;
    2854                 :       2667 :     mbridge_unregister_bundle(ofproto->mbridge, bundle);
    2855                 :            : 
    2856                 :       2667 :     xlate_txn_start();
    2857                 :       2667 :     xlate_bundle_remove(bundle);
    2858                 :       2667 :     xlate_txn_commit();
    2859                 :            : 
    2860 [ +  + ][ +  + ]:       5088 :     LIST_FOR_EACH_SAFE (port, next_port, bundle_node, &bundle->ports) {
    2861                 :       2421 :         bundle_del_port(port);
    2862                 :            :     }
    2863                 :            : 
    2864                 :       2667 :     bundle_flush_macs(bundle, true);
    2865                 :       2667 :     hmap_remove(&ofproto->bundles, &bundle->hmap_node);
    2866                 :       2667 :     free(bundle->name);
    2867                 :       2667 :     free(bundle->trunks);
    2868                 :       2667 :     lacp_unref(bundle->lacp);
    2869                 :       2667 :     bond_unref(bundle->bond);
    2870                 :       2667 :     free(bundle);
    2871                 :            : }
    2872                 :            : 
    2873                 :            : static int
    2874                 :      34469 : bundle_set(struct ofproto *ofproto_, void *aux,
    2875                 :            :            const struct ofproto_bundle_settings *s)
    2876                 :            : {
    2877                 :      34469 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    2878                 :      34469 :     bool need_flush = false;
    2879                 :            :     struct ofport_dpif *port;
    2880                 :            :     struct ofbundle *bundle;
    2881                 :            :     unsigned long *trunks;
    2882                 :            :     int vlan;
    2883                 :            :     size_t i;
    2884                 :            :     bool ok;
    2885                 :            : 
    2886         [ +  + ]:      34469 :     if (!s) {
    2887                 :       2667 :         bundle_destroy(bundle_lookup(ofproto, aux));
    2888                 :       2667 :         return 0;
    2889                 :            :     }
    2890                 :            : 
    2891 [ +  + ][ -  + ]:      31802 :     ovs_assert(s->n_slaves == 1 || s->bond != NULL);
    2892         [ -  + ]:      31802 :     ovs_assert((s->lacp != NULL) == (s->lacp_slaves != NULL));
    2893                 :            : 
    2894                 :      31802 :     bundle = bundle_lookup(ofproto, aux);
    2895         [ +  + ]:      31802 :     if (!bundle) {
    2896                 :       2667 :         bundle = xmalloc(sizeof *bundle);
    2897                 :            : 
    2898                 :       2667 :         bundle->ofproto = ofproto;
    2899                 :       2667 :         hmap_insert(&ofproto->bundles, &bundle->hmap_node,
    2900                 :            :                     hash_pointer(aux, 0));
    2901                 :       2667 :         bundle->aux = aux;
    2902                 :       2667 :         bundle->name = NULL;
    2903                 :            : 
    2904                 :       2667 :         ovs_list_init(&bundle->ports);
    2905                 :       2667 :         bundle->vlan_mode = PORT_VLAN_TRUNK;
    2906                 :       2667 :         bundle->vlan = -1;
    2907                 :       2667 :         bundle->trunks = NULL;
    2908                 :       2667 :         bundle->use_priority_tags = s->use_priority_tags;
    2909                 :       2667 :         bundle->lacp = NULL;
    2910                 :       2667 :         bundle->bond = NULL;
    2911                 :            : 
    2912                 :       2667 :         bundle->floodable = true;
    2913                 :       2667 :         mbridge_register_bundle(ofproto->mbridge, bundle);
    2914                 :            :     }
    2915                 :            : 
    2916 [ +  + ][ -  + ]:      31802 :     if (!bundle->name || strcmp(s->name, bundle->name)) {
    2917                 :       2667 :         free(bundle->name);
    2918                 :       2667 :         bundle->name = xstrdup(s->name);
    2919                 :            :     }
    2920                 :            : 
    2921                 :            :     /* LACP. */
    2922         [ +  + ]:      31802 :     if (s->lacp) {
    2923                 :         20 :         ofproto->lacp_enabled = true;
    2924         [ +  + ]:         20 :         if (!bundle->lacp) {
    2925                 :         13 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    2926                 :         13 :             bundle->lacp = lacp_create();
    2927                 :            :         }
    2928                 :         20 :         lacp_configure(bundle->lacp, s->lacp);
    2929                 :            :     } else {
    2930                 :      31782 :         lacp_unref(bundle->lacp);
    2931                 :      31782 :         bundle->lacp = NULL;
    2932                 :            :     }
    2933                 :            : 
    2934                 :            :     /* Update set of ports. */
    2935                 :      31802 :     ok = true;
    2936         [ +  + ]:      63639 :     for (i = 0; i < s->n_slaves; i++) {
    2937 [ +  + ][ -  + ]:      31837 :         if (!bundle_add_port(bundle, s->slaves[i],
    2938                 :      31878 :                              s->lacp ? &s->lacp_slaves[i] : NULL)) {
    2939                 :          0 :             ok = false;
    2940                 :            :         }
    2941                 :            :     }
    2942 [ +  - ][ -  + ]:      31802 :     if (!ok || ovs_list_size(&bundle->ports) != s->n_slaves) {
    2943                 :            :         struct ofport_dpif *next_port;
    2944                 :            : 
    2945 [ #  # ][ #  # ]:          0 :         LIST_FOR_EACH_SAFE (port, next_port, bundle_node, &bundle->ports) {
    2946         [ #  # ]:          0 :             for (i = 0; i < s->n_slaves; i++) {
    2947         [ #  # ]:          0 :                 if (s->slaves[i] == port->up.ofp_port) {
    2948                 :          0 :                     goto found;
    2949                 :            :                 }
    2950                 :            :             }
    2951                 :            : 
    2952                 :          0 :             bundle_del_port(port);
    2953                 :            :         found: ;
    2954                 :            :         }
    2955                 :            :     }
    2956         [ -  + ]:      31802 :     ovs_assert(ovs_list_size(&bundle->ports) <= s->n_slaves);
    2957                 :            : 
    2958         [ -  + ]:      31802 :     if (ovs_list_is_empty(&bundle->ports)) {
    2959                 :          0 :         bundle_destroy(bundle);
    2960                 :          0 :         return EINVAL;
    2961                 :            :     }
    2962                 :            : 
    2963                 :            :     /* Set VLAN tagging mode */
    2964         [ +  + ]:      31802 :     if (s->vlan_mode != bundle->vlan_mode
    2965         [ -  + ]:      31787 :         || s->use_priority_tags != bundle->use_priority_tags) {
    2966                 :         15 :         bundle->vlan_mode = s->vlan_mode;
    2967                 :         15 :         bundle->use_priority_tags = s->use_priority_tags;
    2968                 :         15 :         need_flush = true;
    2969                 :            :     }
    2970                 :            : 
    2971                 :            :     /* Set VLAN tag. */
    2972                 :      63604 :     vlan = (s->vlan_mode == PORT_VLAN_TRUNK ? -1
    2973 [ +  + ][ +  - ]:      31832 :             : s->vlan >= 0 && s->vlan <= 4095 ? s->vlan
    2974         [ +  - ]:         30 :             : 0);
    2975         [ +  + ]:      31802 :     if (vlan != bundle->vlan) {
    2976                 :         15 :         bundle->vlan = vlan;
    2977                 :         15 :         need_flush = true;
    2978                 :            :     }
    2979                 :            : 
    2980                 :            :     /* Get trunked VLANs. */
    2981   [ +  +  +  - ]:      31802 :     switch (s->vlan_mode) {
    2982                 :            :     case PORT_VLAN_ACCESS:
    2983                 :         11 :         trunks = NULL;
    2984                 :         11 :         break;
    2985                 :            : 
    2986                 :            :     case PORT_VLAN_TRUNK:
    2987                 :      31787 :         trunks = CONST_CAST(unsigned long *, s->trunks);
    2988                 :      31787 :         break;
    2989                 :            : 
    2990                 :            :     case PORT_VLAN_NATIVE_UNTAGGED:
    2991                 :            :     case PORT_VLAN_NATIVE_TAGGED:
    2992 [ +  - ][ +  + ]:          4 :         if (vlan != 0 && (!s->trunks
    2993         [ +  - ]:          2 :                           || !bitmap_is_set(s->trunks, vlan)
    2994         [ -  + ]:          2 :                           || bitmap_is_set(s->trunks, 0))) {
    2995                 :            :             /* Force trunking the native VLAN and prohibit trunking VLAN 0. */
    2996         [ -  + ]:          2 :             if (s->trunks) {
    2997                 :          0 :                 trunks = bitmap_clone(s->trunks, 4096);
    2998                 :            :             } else {
    2999                 :          2 :                 trunks = bitmap_allocate1(4096);
    3000                 :            :             }
    3001                 :          2 :             bitmap_set1(trunks, vlan);
    3002                 :          2 :             bitmap_set0(trunks, 0);
    3003                 :            :         } else {
    3004                 :          2 :             trunks = CONST_CAST(unsigned long *, s->trunks);
    3005                 :            :         }
    3006                 :          4 :         break;
    3007                 :            : 
    3008                 :            :     default:
    3009                 :          0 :         OVS_NOT_REACHED();
    3010                 :            :     }
    3011         [ +  + ]:      31802 :     if (!vlan_bitmap_equal(trunks, bundle->trunks)) {
    3012                 :          5 :         free(bundle->trunks);
    3013         [ +  + ]:          5 :         if (trunks == s->trunks) {
    3014                 :          3 :             bundle->trunks = vlan_bitmap_clone(trunks);
    3015                 :            :         } else {
    3016                 :          2 :             bundle->trunks = trunks;
    3017                 :          2 :             trunks = NULL;
    3018                 :            :         }
    3019                 :          5 :         need_flush = true;
    3020                 :            :     }
    3021         [ -  + ]:      31802 :     if (trunks != s->trunks) {
    3022                 :          0 :         free(trunks);
    3023                 :            :     }
    3024                 :            : 
    3025                 :            :     /* Bonding. */
    3026         [ +  + ]:      31802 :     if (!ovs_list_is_short(&bundle->ports)) {
    3027                 :         32 :         bundle->ofproto->has_bonded_bundles = true;
    3028         [ +  + ]:         32 :         if (bundle->bond) {
    3029         [ -  + ]:         13 :             if (bond_reconfigure(bundle->bond, s->bond)) {
    3030                 :         13 :                 ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3031                 :            :             }
    3032                 :            :         } else {
    3033                 :         19 :             bundle->bond = bond_create(s->bond, ofproto);
    3034                 :         19 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3035                 :            :         }
    3036                 :            : 
    3037         [ +  + ]:         99 :         LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
    3038                 :         67 :             bond_slave_register(bundle->bond, port,
    3039                 :            :                                 port->up.ofp_port, port->up.netdev);
    3040                 :            :         }
    3041                 :            :     } else {
    3042                 :      31770 :         bond_unref(bundle->bond);
    3043                 :      31770 :         bundle->bond = NULL;
    3044                 :            :     }
    3045                 :            : 
    3046                 :            :     /* If we changed something that would affect MAC learning, un-learn
    3047                 :            :      * everything on this port and force flow revalidation. */
    3048         [ +  + ]:      31802 :     if (need_flush) {
    3049                 :         16 :         bundle_flush_macs(bundle, false);
    3050                 :            :     }
    3051                 :            : 
    3052                 :      31802 :     return 0;
    3053                 :            : }
    3054                 :            : 
    3055                 :            : static void
    3056                 :       5660 : bundle_remove(struct ofport *port_)
    3057                 :            : {
    3058                 :       5660 :     struct ofport_dpif *port = ofport_dpif_cast(port_);
    3059                 :       5660 :     struct ofbundle *bundle = port->bundle;
    3060                 :            : 
    3061         [ +  + ]:       5660 :     if (bundle) {
    3062                 :        268 :         bundle_del_port(port);
    3063         [ +  - ]:        268 :         if (ovs_list_is_empty(&bundle->ports)) {
    3064                 :        268 :             bundle_destroy(bundle);
    3065         [ #  # ]:          0 :         } else if (ovs_list_is_short(&bundle->ports)) {
    3066                 :          0 :             bond_unref(bundle->bond);
    3067                 :          0 :             bundle->bond = NULL;
    3068                 :            :         }
    3069                 :            :     }
    3070                 :       5660 : }
    3071                 :            : 
    3072                 :            : static void
    3073                 :         80 : send_pdu_cb(void *port_, const void *pdu, size_t pdu_size)
    3074                 :            : {
    3075                 :            :     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 10);
    3076                 :         80 :     struct ofport_dpif *port = port_;
    3077                 :            :     struct eth_addr ea;
    3078                 :            :     int error;
    3079                 :            : 
    3080                 :         80 :     error = netdev_get_etheraddr(port->up.netdev, &ea);
    3081         [ +  - ]:         80 :     if (!error) {
    3082                 :            :         struct dp_packet packet;
    3083                 :            :         void *packet_pdu;
    3084                 :            : 
    3085                 :         80 :         dp_packet_init(&packet, 0);
    3086                 :         80 :         packet_pdu = eth_compose(&packet, eth_addr_lacp, ea, ETH_TYPE_LACP,
    3087                 :            :                                  pdu_size);
    3088                 :         80 :         memcpy(packet_pdu, pdu, pdu_size);
    3089                 :            : 
    3090                 :         80 :         ofproto_dpif_send_packet(port, false, &packet);
    3091                 :         80 :         dp_packet_uninit(&packet);
    3092                 :            :     } else {
    3093         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "port %s: cannot obtain Ethernet address of iface "
    3094                 :            :                     "%s (%s)", port->bundle->name,
    3095                 :            :                     netdev_get_name(port->up.netdev), ovs_strerror(error));
    3096                 :            :     }
    3097                 :         80 : }
    3098                 :            : 
    3099                 :            : static void
    3100                 :          8 : bundle_send_learning_packets(struct ofbundle *bundle)
    3101                 :            : {
    3102                 :          8 :     struct ofproto_dpif *ofproto = bundle->ofproto;
    3103                 :            :     int error, n_packets, n_errors;
    3104                 :            :     struct mac_entry *e;
    3105                 :            :     struct pkt_list {
    3106                 :            :         struct ovs_list list_node;
    3107                 :            :         struct ofport_dpif *port;
    3108                 :            :         struct dp_packet *pkt;
    3109                 :            :     } *pkt_node;
    3110                 :            :     struct ovs_list packets;
    3111                 :            : 
    3112                 :          8 :     ovs_list_init(&packets);
    3113                 :          8 :     ovs_rwlock_rdlock(&ofproto->ml->rwlock);
    3114         [ +  + ]:         10 :     LIST_FOR_EACH (e, lru_node, &ofproto->ml->lrus) {
    3115         [ +  - ]:          2 :         if (mac_entry_get_port(ofproto->ml, e) != bundle) {
    3116                 :          2 :             pkt_node = xmalloc(sizeof *pkt_node);
    3117                 :          2 :             pkt_node->pkt = bond_compose_learning_packet(bundle->bond,
    3118                 :          2 :                                                          e->mac, e->vlan,
    3119                 :          2 :                                                          (void **)&pkt_node->port);
    3120                 :          2 :             ovs_list_push_back(&packets, &pkt_node->list_node);
    3121                 :            :         }
    3122                 :            :     }
    3123                 :          8 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    3124                 :            : 
    3125                 :          8 :     error = n_packets = n_errors = 0;
    3126         [ +  + ]:         10 :     LIST_FOR_EACH_POP (pkt_node, list_node, &packets) {
    3127                 :            :         int ret;
    3128                 :            : 
    3129                 :          2 :         ret = ofproto_dpif_send_packet(pkt_node->port, false, pkt_node->pkt);
    3130                 :          2 :         dp_packet_delete(pkt_node->pkt);
    3131                 :          2 :         free(pkt_node);
    3132         [ -  + ]:          2 :         if (ret) {
    3133                 :          0 :             error = ret;
    3134                 :          0 :             n_errors++;
    3135                 :            :         }
    3136                 :          2 :         n_packets++;
    3137                 :            :     }
    3138                 :            : 
    3139         [ -  + ]:          8 :     if (n_errors) {
    3140                 :            :         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
    3141         [ #  # ]:          0 :         VLOG_WARN_RL(&rl, "bond %s: %d errors sending %d gratuitous learning "
    3142                 :            :                      "packets, last error was: %s",
    3143                 :            :                      bundle->name, n_errors, n_packets, ovs_strerror(error));
    3144                 :            :     } else {
    3145         [ +  - ]:          8 :         VLOG_DBG("bond %s: sent %d gratuitous learning packets",
    3146                 :            :                  bundle->name, n_packets);
    3147                 :            :     }
    3148                 :          8 : }
    3149                 :            : 
    3150                 :            : static void
    3151                 :      15523 : bundle_run(struct ofbundle *bundle)
    3152                 :            : {
    3153         [ +  + ]:      15523 :     if (bundle->lacp) {
    3154                 :       3909 :         lacp_run(bundle->lacp, send_pdu_cb);
    3155                 :            :     }
    3156         [ +  + ]:      15523 :     if (bundle->bond) {
    3157                 :            :         struct ofport_dpif *port;
    3158                 :            : 
    3159         [ +  + ]:      20138 :         LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
    3160                 :      14728 :             bond_slave_set_may_enable(bundle->bond, port, port->may_enable);
    3161                 :            :         }
    3162                 :            : 
    3163         [ +  + ]:       5410 :         if (bond_run(bundle->bond, lacp_status(bundle->lacp))) {
    3164                 :         44 :             bundle->ofproto->backer->need_revalidate = REV_BOND;
    3165                 :            :         }
    3166                 :            : 
    3167         [ +  + ]:       5410 :         if (bond_should_send_learning_packets(bundle->bond)) {
    3168                 :          8 :             bundle_send_learning_packets(bundle);
    3169                 :            :         }
    3170                 :            :     }
    3171                 :      15523 : }
    3172                 :            : 
    3173                 :            : static void
    3174                 :      15495 : bundle_wait(struct ofbundle *bundle)
    3175                 :            : {
    3176         [ +  + ]:      15495 :     if (bundle->lacp) {
    3177                 :       3902 :         lacp_wait(bundle->lacp);
    3178                 :            :     }
    3179         [ +  + ]:      15495 :     if (bundle->bond) {
    3180                 :       5397 :         bond_wait(bundle->bond);
    3181                 :            :     }
    3182                 :      15495 : }
    3183                 :            : 
    3184                 :            : /* Mirrors. */
    3185                 :            : 
    3186                 :            : static int
    3187                 :         44 : mirror_set__(struct ofproto *ofproto_, void *aux,
    3188                 :            :              const struct ofproto_mirror_settings *s)
    3189                 :            : {
    3190                 :         44 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3191                 :            :     struct ofbundle **srcs, **dsts;
    3192                 :            :     int error;
    3193                 :            :     size_t i;
    3194                 :            : 
    3195         [ +  + ]:         44 :     if (!s) {
    3196                 :         22 :         mirror_destroy(ofproto->mbridge, aux);
    3197                 :         22 :         return 0;
    3198                 :            :     }
    3199                 :            : 
    3200                 :         22 :     srcs = xmalloc(s->n_srcs * sizeof *srcs);
    3201                 :         22 :     dsts = xmalloc(s->n_dsts * sizeof *dsts);
    3202                 :            : 
    3203         [ +  + ]:         89 :     for (i = 0; i < s->n_srcs; i++) {
    3204                 :         67 :         srcs[i] = bundle_lookup(ofproto, s->srcs[i]);
    3205                 :            :     }
    3206                 :            : 
    3207         [ +  + ]:         92 :     for (i = 0; i < s->n_dsts; i++) {
    3208                 :         70 :         dsts[i] = bundle_lookup(ofproto, s->dsts[i]);
    3209                 :            :     }
    3210                 :            : 
    3211                 :         22 :     error = mirror_set(ofproto->mbridge, aux, s->name, srcs, s->n_srcs, dsts,
    3212                 :            :                        s->n_dsts, s->src_vlans,
    3213                 :            :                        bundle_lookup(ofproto, s->out_bundle),
    3214                 :         44 :                        s->snaplen, s->out_vlan);
    3215                 :         22 :     free(srcs);
    3216                 :         22 :     free(dsts);
    3217                 :         22 :     return error;
    3218                 :            : }
    3219                 :            : 
    3220                 :            : static int
    3221                 :          0 : mirror_get_stats__(struct ofproto *ofproto, void *aux,
    3222                 :            :                    uint64_t *packets, uint64_t *bytes)
    3223                 :            : {
    3224                 :          0 :     return mirror_get_stats(ofproto_dpif_cast(ofproto)->mbridge, aux, packets,
    3225                 :            :                             bytes);
    3226                 :            : }
    3227                 :            : 
    3228                 :            : static int
    3229                 :       4700 : set_flood_vlans(struct ofproto *ofproto_, unsigned long *flood_vlans)
    3230                 :            : {
    3231                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3232                 :       4700 :     ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    3233         [ -  + ]:       4700 :     if (mac_learning_set_flood_vlans(ofproto->ml, flood_vlans)) {
    3234                 :          0 :         mac_learning_flush(ofproto->ml);
    3235                 :            :     }
    3236                 :       4700 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    3237                 :       4700 :     return 0;
    3238                 :            : }
    3239                 :            : 
    3240                 :            : static bool
    3241                 :         15 : is_mirror_output_bundle(const struct ofproto *ofproto_, void *aux)
    3242                 :            : {
    3243                 :         15 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3244                 :         15 :     struct ofbundle *bundle = bundle_lookup(ofproto, aux);
    3245 [ +  - ][ -  + ]:         15 :     return bundle && mirror_bundle_out(ofproto->mbridge, bundle) != 0;
    3246                 :            : }
    3247                 :            : 
    3248                 :            : static void
    3249                 :          0 : forward_bpdu_changed(struct ofproto *ofproto_)
    3250                 :            : {
    3251                 :          0 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3252                 :          0 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3253                 :          0 : }
    3254                 :            : 
    3255                 :            : static void
    3256                 :       4700 : set_mac_table_config(struct ofproto *ofproto_, unsigned int idle_time,
    3257                 :            :                      size_t max_entries)
    3258                 :            : {
    3259                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3260                 :       4700 :     ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    3261                 :       4700 :     mac_learning_set_idle_time(ofproto->ml, idle_time);
    3262                 :       4700 :     mac_learning_set_max_entries(ofproto->ml, max_entries);
    3263                 :       4700 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    3264                 :       4700 : }
    3265                 :            : 
    3266                 :            : /* Configures multicast snooping on 'ofport' using the settings
    3267                 :            :  * defined in 's'. */
    3268                 :            : static int
    3269                 :       4700 : set_mcast_snooping(struct ofproto *ofproto_,
    3270                 :            :                    const struct ofproto_mcast_snooping_settings *s)
    3271                 :            : {
    3272                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3273                 :            : 
    3274                 :            :     /* Only revalidate flows if the configuration changed. */
    3275         [ -  + ]:       4700 :     if (!s != !ofproto->ms) {
    3276                 :          0 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3277                 :            :     }
    3278                 :            : 
    3279         [ -  + ]:       4700 :     if (s) {
    3280         [ #  # ]:          0 :         if (!ofproto->ms) {
    3281                 :          0 :             ofproto->ms = mcast_snooping_create();
    3282                 :            :         }
    3283                 :            : 
    3284                 :          0 :         ovs_rwlock_wrlock(&ofproto->ms->rwlock);
    3285                 :          0 :         mcast_snooping_set_idle_time(ofproto->ms, s->idle_time);
    3286                 :          0 :         mcast_snooping_set_max_entries(ofproto->ms, s->max_entries);
    3287         [ #  # ]:          0 :         if (mcast_snooping_set_flood_unreg(ofproto->ms, s->flood_unreg)) {
    3288                 :          0 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3289                 :            :         }
    3290                 :          0 :         ovs_rwlock_unlock(&ofproto->ms->rwlock);
    3291                 :            :     } else {
    3292                 :       4700 :         mcast_snooping_unref(ofproto->ms);
    3293                 :       4700 :         ofproto->ms = NULL;
    3294                 :            :     }
    3295                 :            : 
    3296                 :       4700 :     return 0;
    3297                 :            : }
    3298                 :            : 
    3299                 :            : /* Configures multicast snooping port's flood settings on 'ofproto'. */
    3300                 :            : static int
    3301                 :          0 : set_mcast_snooping_port(struct ofproto *ofproto_, void *aux,
    3302                 :            :                         const struct ofproto_mcast_snooping_port_settings *s)
    3303                 :            : {
    3304                 :          0 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3305                 :          0 :     struct ofbundle *bundle = bundle_lookup(ofproto, aux);
    3306                 :            : 
    3307 [ #  # ][ #  # ]:          0 :     if (ofproto->ms && s) {
    3308                 :          0 :         ovs_rwlock_wrlock(&ofproto->ms->rwlock);
    3309                 :          0 :         mcast_snooping_set_port_flood(ofproto->ms, bundle, s->flood);
    3310                 :          0 :         mcast_snooping_set_port_flood_reports(ofproto->ms, bundle,
    3311                 :          0 :                                               s->flood_reports);
    3312                 :          0 :         ovs_rwlock_unlock(&ofproto->ms->rwlock);
    3313                 :            :     }
    3314                 :          0 :     return 0;
    3315                 :            : }
    3316                 :            : 
    3317                 :            : 
    3318                 :            : /* Ports. */
    3319                 :            : 
    3320                 :            : struct ofport_dpif *
    3321                 :      40604 : ofp_port_to_ofport(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
    3322                 :            : {
    3323                 :      40604 :     struct ofport *ofport = ofproto_get_port(&ofproto->up, ofp_port);
    3324         [ +  + ]:      40604 :     return ofport ? ofport_dpif_cast(ofport) : NULL;
    3325                 :            : }
    3326                 :            : 
    3327                 :            : static void
    3328                 :      16635 : ofproto_port_from_dpif_port(struct ofproto_dpif *ofproto,
    3329                 :            :                             struct ofproto_port *ofproto_port,
    3330                 :            :                             struct dpif_port *dpif_port)
    3331                 :            : {
    3332                 :      16635 :     ofproto_port->name = dpif_port->name;
    3333                 :      16635 :     ofproto_port->type = dpif_port->type;
    3334                 :      16635 :     ofproto_port->ofp_port = odp_port_to_ofp_port(ofproto, dpif_port->port_no);
    3335                 :      16635 : }
    3336                 :            : 
    3337                 :            : static void
    3338                 :       5328 : ofport_update_peer(struct ofport_dpif *ofport)
    3339                 :            : {
    3340                 :            :     const struct ofproto_dpif *ofproto;
    3341                 :            :     struct dpif_backer *backer;
    3342                 :            :     char *peer_name;
    3343                 :            : 
    3344         [ +  + ]:       5328 :     if (!netdev_vport_is_patch(ofport->up.netdev)) {
    3345                 :       5004 :         return;
    3346                 :            :     }
    3347                 :            : 
    3348                 :        324 :     backer = ofproto_dpif_cast(ofport->up.ofproto)->backer;
    3349                 :        324 :     backer->need_revalidate = REV_RECONFIGURE;
    3350                 :            : 
    3351         [ +  + ]:        324 :     if (ofport->peer) {
    3352                 :          2 :         ofport->peer->peer = NULL;
    3353                 :          2 :         ofport->peer = NULL;
    3354                 :            :     }
    3355                 :            : 
    3356                 :        324 :     peer_name = netdev_vport_patch_peer(ofport->up.netdev);
    3357         [ -  + ]:        324 :     if (!peer_name) {
    3358                 :          0 :         return;
    3359                 :            :     }
    3360                 :            : 
    3361 [ +  + ][ -  + ]:        794 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
    3362                 :            :         struct ofport *peer_ofport;
    3363                 :            :         struct ofport_dpif *peer;
    3364                 :            :         char *peer_peer;
    3365                 :            : 
    3366         [ -  + ]:        631 :         if (ofproto->backer != backer) {
    3367                 :          0 :             continue;
    3368                 :            :         }
    3369                 :            : 
    3370                 :        631 :         peer_ofport = shash_find_data(&ofproto->up.port_by_name, peer_name);
    3371         [ +  + ]:        631 :         if (!peer_ofport) {
    3372                 :        470 :             continue;
    3373                 :            :         }
    3374                 :            : 
    3375                 :        161 :         peer = ofport_dpif_cast(peer_ofport);
    3376                 :        161 :         peer_peer = netdev_vport_patch_peer(peer->up.netdev);
    3377 [ +  - ][ +  - ]:        161 :         if (peer_peer && !strcmp(netdev_get_name(ofport->up.netdev),
    3378                 :            :                                  peer_peer)) {
    3379                 :        161 :             ofport->peer = peer;
    3380                 :        161 :             ofport->peer->peer = ofport;
    3381                 :            :         }
    3382                 :        161 :         free(peer_peer);
    3383                 :            : 
    3384                 :        161 :         break;
    3385                 :            :     }
    3386                 :        324 :     free(peer_name);
    3387                 :            : }
    3388                 :            : 
    3389                 :            : static void
    3390                 :      35828 : port_run(struct ofport_dpif *ofport)
    3391                 :            : {
    3392                 :      35828 :     long long int carrier_seq = netdev_get_carrier_resets(ofport->up.netdev);
    3393                 :      35828 :     bool carrier_changed = carrier_seq != ofport->carrier_seq;
    3394                 :      35828 :     bool enable = netdev_get_carrier(ofport->up.netdev);
    3395                 :      35828 :     bool cfm_enable = false;
    3396                 :      35828 :     bool bfd_enable = false;
    3397                 :            : 
    3398                 :      35828 :     ofport->carrier_seq = carrier_seq;
    3399                 :            : 
    3400         [ +  + ]:      35828 :     if (ofport->cfm) {
    3401                 :         90 :         int cfm_opup = cfm_get_opup(ofport->cfm);
    3402                 :            : 
    3403                 :         90 :         cfm_enable = !cfm_get_fault(ofport->cfm);
    3404                 :            : 
    3405         [ +  + ]:         90 :         if (cfm_opup >= 0) {
    3406 [ +  + ][ +  - ]:         73 :             cfm_enable = cfm_enable && cfm_opup;
    3407                 :            :         }
    3408                 :            :     }
    3409                 :            : 
    3410         [ +  + ]:      35828 :     if (ofport->bfd) {
    3411                 :      20186 :         bfd_enable = bfd_forwarding(ofport->bfd);
    3412                 :            :     }
    3413                 :            : 
    3414 [ +  + ][ +  + ]:      35828 :     if (ofport->bfd || ofport->cfm) {
    3415 [ +  - ][ +  + ]:      20263 :         enable = enable && (cfm_enable || bfd_enable);
                 [ +  + ]
    3416                 :            :     }
    3417                 :            : 
    3418         [ +  + ]:      35828 :     if (ofport->bundle) {
    3419 [ +  + ][ +  + ]:      35748 :         enable = enable && lacp_slave_may_enable(ofport->bundle->lacp, ofport);
    3420         [ +  + ]:      35748 :         if (carrier_changed) {
    3421                 :         97 :             lacp_slave_carrier_changed(ofport->bundle->lacp, ofport);
    3422                 :            :         }
    3423                 :            :     }
    3424                 :            : 
    3425         [ +  + ]:      35828 :     if (ofport->may_enable != enable) {
    3426                 :        867 :         struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    3427                 :            : 
    3428                 :        867 :         ofproto->backer->need_revalidate = REV_PORT_TOGGLED;
    3429                 :            : 
    3430         [ +  + ]:        867 :         if (ofport->rstp_port) {
    3431                 :          2 :             rstp_port_set_mac_operational(ofport->rstp_port, enable);
    3432                 :            :         }
    3433                 :            :     }
    3434                 :            : 
    3435                 :      35828 :     ofport->may_enable = enable;
    3436                 :      35828 : }
    3437                 :            : 
    3438                 :            : static int
    3439                 :      40308 : port_query_by_name(const struct ofproto *ofproto_, const char *devname,
    3440                 :            :                    struct ofproto_port *ofproto_port)
    3441                 :            : {
    3442                 :      40308 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3443                 :            :     struct dpif_port dpif_port;
    3444                 :            :     int error;
    3445                 :            : 
    3446         [ +  + ]:      40308 :     if (sset_contains(&ofproto->ghost_ports, devname)) {
    3447                 :      23366 :         const char *type = netdev_get_type_from_name(devname);
    3448                 :            : 
    3449                 :            :         /* We may be called before ofproto->up.port_by_name is populated with
    3450                 :            :          * the appropriate ofport.  For this reason, we must get the name and
    3451                 :            :          * type from the netdev layer directly. */
    3452         [ +  + ]:      23366 :         if (type) {
    3453                 :            :             const struct ofport *ofport;
    3454                 :            : 
    3455                 :      23188 :             ofport = shash_find_data(&ofproto->up.port_by_name, devname);
    3456         [ +  + ]:      23188 :             ofproto_port->ofp_port = ofport ? ofport->ofp_port : OFPP_NONE;
    3457                 :      23188 :             ofproto_port->name = xstrdup(devname);
    3458                 :      23188 :             ofproto_port->type = xstrdup(type);
    3459                 :      23188 :             return 0;
    3460                 :            :         }
    3461                 :        178 :         return ENODEV;
    3462                 :            :     }
    3463                 :            : 
    3464         [ +  + ]:      16942 :     if (!sset_contains(&ofproto->ports, devname)) {
    3465                 :         23 :         return ENODEV;
    3466                 :            :     }
    3467                 :      16919 :     error = dpif_port_query_by_name(ofproto->backer->dpif,
    3468                 :            :                                     devname, &dpif_port);
    3469         [ +  + ]:      16919 :     if (!error) {
    3470                 :      16635 :         ofproto_port_from_dpif_port(ofproto, ofproto_port, &dpif_port);
    3471                 :            :     }
    3472                 :      40308 :     return error;
    3473                 :            : }
    3474                 :            : 
    3475                 :            : static int
    3476                 :       2690 : port_add(struct ofproto *ofproto_, struct netdev *netdev)
    3477                 :            : {
    3478                 :       2690 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3479                 :       2690 :     const char *devname = netdev_get_name(netdev);
    3480                 :            :     char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
    3481                 :            :     const char *dp_port_name;
    3482                 :            : 
    3483         [ +  + ]:       2690 :     if (netdev_vport_is_patch(netdev)) {
    3484                 :        322 :         sset_add(&ofproto->ghost_ports, netdev_get_name(netdev));
    3485                 :        322 :         return 0;
    3486                 :            :     }
    3487                 :            : 
    3488                 :       2368 :     dp_port_name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
    3489         [ +  + ]:       2368 :     if (!dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
    3490                 :       2134 :         odp_port_t port_no = ODPP_NONE;
    3491                 :            :         int error;
    3492                 :            : 
    3493                 :       2134 :         error = dpif_port_add(ofproto->backer->dpif, netdev, &port_no);
    3494         [ -  + ]:       2134 :         if (error) {
    3495                 :          0 :             return error;
    3496                 :            :         }
    3497         [ +  + ]:       2134 :         if (netdev_get_tunnel_config(netdev)) {
    3498                 :       2134 :             simap_put(&ofproto->backer->tnl_backers,
    3499                 :            :                       dp_port_name, odp_to_u32(port_no));
    3500                 :            :         }
    3501                 :            :     }
    3502                 :            : 
    3503         [ +  + ]:       2368 :     if (netdev_get_tunnel_config(netdev)) {
    3504                 :        320 :         sset_add(&ofproto->ghost_ports, devname);
    3505                 :            :     } else {
    3506                 :       2048 :         sset_add(&ofproto->ports, devname);
    3507                 :            :     }
    3508                 :       2690 :     return 0;
    3509                 :            : }
    3510                 :            : 
    3511                 :            : static int
    3512                 :        388 : port_del(struct ofproto *ofproto_, ofp_port_t ofp_port)
    3513                 :            : {
    3514                 :        388 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3515                 :        388 :     struct ofport_dpif *ofport = ofp_port_to_ofport(ofproto, ofp_port);
    3516                 :        388 :     int error = 0;
    3517                 :            : 
    3518         [ +  + ]:        388 :     if (!ofport) {
    3519                 :         82 :         return 0;
    3520                 :            :     }
    3521                 :            : 
    3522                 :        306 :     sset_find_and_delete(&ofproto->ghost_ports,
    3523                 :        306 :                          netdev_get_name(ofport->up.netdev));
    3524                 :        306 :     ofproto->backer->need_revalidate = REV_RECONFIGURE;
    3525 [ +  + ][ +  + ]:        306 :     if (!ofport->is_tunnel && !netdev_vport_is_patch(ofport->up.netdev)) {
    3526                 :        283 :         error = dpif_port_del(ofproto->backer->dpif, ofport->odp_port);
    3527         [ +  - ]:        283 :         if (!error) {
    3528                 :            :             /* The caller is going to close ofport->up.netdev.  If this is a
    3529                 :            :              * bonded port, then the bond is using that netdev, so remove it
    3530                 :            :              * from the bond.  The client will need to reconfigure everything
    3531                 :            :              * after deleting ports, so then the slave will get re-added. */
    3532                 :        283 :             bundle_remove(&ofport->up);
    3533                 :            :         }
    3534                 :            :     }
    3535                 :        306 :     return error;
    3536                 :            : }
    3537                 :            : 
    3538                 :            : static int
    3539                 :      31837 : port_set_config(const struct ofport *ofport_, const struct smap *cfg)
    3540                 :            : {
    3541                 :      31837 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    3542                 :      31837 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    3543                 :            : 
    3544         [ +  + ]:      31837 :     if (sset_contains(&ofproto->ghost_ports,
    3545                 :      31837 :                       netdev_get_name(ofport->up.netdev))) {
    3546                 :      22531 :         return 0;
    3547                 :            :     }
    3548                 :            : 
    3549                 :       9306 :     return dpif_port_set_config(ofproto->backer->dpif, ofport->odp_port, cfg);
    3550                 :            : }
    3551                 :            : 
    3552                 :            : static int
    3553                 :         60 : port_get_stats(const struct ofport *ofport_, struct netdev_stats *stats)
    3554                 :            : {
    3555                 :         60 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    3556                 :            :     int error;
    3557                 :            : 
    3558                 :         60 :     error = netdev_get_stats(ofport->up.netdev, stats);
    3559                 :            : 
    3560 [ +  - ][ +  + ]:         60 :     if (!error && ofport_->ofp_port == OFPP_LOCAL) {
    3561                 :         15 :         struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    3562                 :            : 
    3563                 :         15 :         ovs_mutex_lock(&ofproto->stats_mutex);
    3564                 :            :         /* ofproto->stats.tx_packets represents packets that we created
    3565                 :            :          * internally and sent to some port (e.g. packets sent with
    3566                 :            :          * ofproto_dpif_send_packet()).  Account for them as if they had
    3567                 :            :          * come from OFPP_LOCAL and got forwarded. */
    3568                 :            : 
    3569         [ +  - ]:         15 :         if (stats->rx_packets != UINT64_MAX) {
    3570                 :         15 :             stats->rx_packets += ofproto->stats.tx_packets;
    3571                 :            :         }
    3572                 :            : 
    3573         [ +  - ]:         15 :         if (stats->rx_bytes != UINT64_MAX) {
    3574                 :         15 :             stats->rx_bytes += ofproto->stats.tx_bytes;
    3575                 :            :         }
    3576                 :            : 
    3577                 :            :         /* ofproto->stats.rx_packets represents packets that were received on
    3578                 :            :          * some port and we processed internally and dropped (e.g. STP).
    3579                 :            :          * Account for them as if they had been forwarded to OFPP_LOCAL. */
    3580                 :            : 
    3581         [ +  - ]:         15 :         if (stats->tx_packets != UINT64_MAX) {
    3582                 :         15 :             stats->tx_packets += ofproto->stats.rx_packets;
    3583                 :            :         }
    3584                 :            : 
    3585         [ +  - ]:         15 :         if (stats->tx_bytes != UINT64_MAX) {
    3586                 :         15 :             stats->tx_bytes += ofproto->stats.rx_bytes;
    3587                 :            :         }
    3588                 :         15 :         ovs_mutex_unlock(&ofproto->stats_mutex);
    3589                 :            :     }
    3590                 :            : 
    3591                 :         60 :     return error;
    3592                 :            : }
    3593                 :            : 
    3594                 :            : static int
    3595                 :         14 : port_get_lacp_stats(const struct ofport *ofport_, struct lacp_slave_stats *stats)
    3596                 :            : {
    3597                 :         14 :     struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    3598 [ +  - ][ +  + ]:         14 :     if (ofport->bundle && ofport->bundle->lacp) {
    3599         [ +  - ]:          2 :         if (lacp_get_slave_stats(ofport->bundle->lacp, ofport, stats)) {
    3600                 :          2 :             return 0;
    3601                 :            :         }
    3602                 :            :     }
    3603                 :         12 :     return -1;
    3604                 :            : }
    3605                 :            : 
    3606                 :            : struct port_dump_state {
    3607                 :            :     struct sset_position pos;
    3608                 :            :     bool ghost;
    3609                 :            : 
    3610                 :            :     struct ofproto_port port;
    3611                 :            :     bool has_port;
    3612                 :            : };
    3613                 :            : 
    3614                 :            : static int
    3615                 :       4700 : port_dump_start(const struct ofproto *ofproto_ OVS_UNUSED, void **statep)
    3616                 :            : {
    3617                 :       4700 :     *statep = xzalloc(sizeof(struct port_dump_state));
    3618                 :       4700 :     return 0;
    3619                 :            : }
    3620                 :            : 
    3621                 :            : static int
    3622                 :      38838 : port_dump_next(const struct ofproto *ofproto_, void *state_,
    3623                 :            :                struct ofproto_port *port)
    3624                 :            : {
    3625                 :      38838 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3626                 :      38838 :     struct port_dump_state *state = state_;
    3627                 :            :     const struct sset *sset;
    3628                 :            :     struct sset_node *node;
    3629                 :            : 
    3630         [ +  + ]:      38838 :     if (state->has_port) {
    3631                 :      29438 :         ofproto_port_destroy(&state->port);
    3632                 :      29438 :         state->has_port = false;
    3633                 :            :     }
    3634         [ +  + ]:      38838 :     sset = state->ghost ? &ofproto->ghost_ports : &ofproto->ports;
    3635         [ +  + ]:      38936 :     while ((node = sset_at_position(sset, &state->pos))) {
    3636                 :            :         int error;
    3637                 :            : 
    3638                 :      29536 :         error = port_query_by_name(ofproto_, node->name, &state->port);
    3639         [ +  + ]:      29536 :         if (!error) {
    3640                 :      29438 :             *port = state->port;
    3641                 :      29438 :             state->has_port = true;
    3642                 :      29438 :             return 0;
    3643         [ -  + ]:         98 :         } else if (error != ENODEV) {
    3644                 :          0 :             return error;
    3645                 :            :         }
    3646                 :            :     }
    3647                 :            : 
    3648         [ +  + ]:       9400 :     if (!state->ghost) {
    3649                 :       4700 :         state->ghost = true;
    3650                 :       4700 :         memset(&state->pos, 0, sizeof state->pos);
    3651                 :       4700 :         return port_dump_next(ofproto_, state_, port);
    3652                 :            :     }
    3653                 :            : 
    3654                 :       4700 :     return EOF;
    3655                 :            : }
    3656                 :            : 
    3657                 :            : static int
    3658                 :       4700 : port_dump_done(const struct ofproto *ofproto_ OVS_UNUSED, void *state_)
    3659                 :            : {
    3660                 :       4700 :     struct port_dump_state *state = state_;
    3661                 :            : 
    3662         [ -  + ]:       4700 :     if (state->has_port) {
    3663                 :          0 :         ofproto_port_destroy(&state->port);
    3664                 :            :     }
    3665                 :       4700 :     free(state);
    3666                 :       4700 :     return 0;
    3667                 :            : }
    3668                 :            : 
    3669                 :            : static int
    3670                 :     157606 : port_poll(const struct ofproto *ofproto_, char **devnamep)
    3671                 :            : {
    3672                 :     157606 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3673                 :            : 
    3674         [ -  + ]:     157606 :     if (ofproto->port_poll_errno) {
    3675                 :          0 :         int error = ofproto->port_poll_errno;
    3676                 :          0 :         ofproto->port_poll_errno = 0;
    3677                 :          0 :         return error;
    3678                 :            :     }
    3679                 :            : 
    3680         [ +  + ]:     157606 :     if (sset_is_empty(&ofproto->port_poll_set)) {
    3681                 :     157605 :         return EAGAIN;
    3682                 :            :     }
    3683                 :            : 
    3684                 :          1 :     *devnamep = sset_pop(&ofproto->port_poll_set);
    3685                 :          1 :     return 0;
    3686                 :            : }
    3687                 :            : 
    3688                 :            : static void
    3689                 :     153645 : port_poll_wait(const struct ofproto *ofproto_)
    3690                 :            : {
    3691                 :     153645 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    3692                 :     153645 :     dpif_port_poll_wait(ofproto->backer->dpif);
    3693                 :     153645 : }
    3694                 :            : 
    3695                 :            : static int
    3696                 :      36468 : port_is_lacp_current(const struct ofport *ofport_)
    3697                 :            : {
    3698                 :      36468 :     const struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
    3699         [ +  + ]:      72936 :     return (ofport->bundle && ofport->bundle->lacp
    3700                 :        145 :             ? lacp_slave_is_current(ofport->bundle->lacp, ofport)
    3701         [ +  - ]:      72936 :             : -1);
    3702                 :            : }
    3703                 :            : 
    3704                 :            : /* If 'rule' is an OpenFlow rule, that has expired according to OpenFlow rules,
    3705                 :            :  * then delete it entirely. */
    3706                 :            : static void
    3707                 :        374 : rule_expire(struct rule_dpif *rule, long long now)
    3708                 :            :     OVS_REQUIRES(ofproto_mutex)
    3709                 :            : {
    3710                 :            :     uint16_t hard_timeout, idle_timeout;
    3711                 :        374 :     int reason = -1;
    3712                 :            : 
    3713                 :        374 :     hard_timeout = rule->up.hard_timeout;
    3714                 :        374 :     idle_timeout = rule->up.idle_timeout;
    3715                 :            : 
    3716                 :            :     /* Has 'rule' expired? */
    3717         [ +  + ]:        374 :     if (hard_timeout) {
    3718                 :            :         long long int modified;
    3719                 :            : 
    3720                 :        164 :         ovs_mutex_lock(&rule->up.mutex);
    3721                 :        164 :         modified = rule->up.modified;
    3722                 :        164 :         ovs_mutex_unlock(&rule->up.mutex);
    3723                 :            : 
    3724         [ +  + ]:        164 :         if (now > modified + hard_timeout * 1000) {
    3725                 :          4 :             reason = OFPRR_HARD_TIMEOUT;
    3726                 :            :         }
    3727                 :            :     }
    3728                 :            : 
    3729 [ +  + ][ +  + ]:        374 :     if (reason < 0 && idle_timeout) {
    3730                 :            :         long long int used;
    3731                 :            : 
    3732                 :        220 :         ovs_mutex_lock(&rule->stats_mutex);
    3733                 :        220 :         used = rule->stats.used;
    3734                 :        220 :         ovs_mutex_unlock(&rule->stats_mutex);
    3735                 :            : 
    3736         [ +  + ]:        220 :         if (now > used + idle_timeout * 1000) {
    3737                 :          1 :             reason = OFPRR_IDLE_TIMEOUT;
    3738                 :            :         }
    3739                 :            :     }
    3740                 :            : 
    3741         [ +  + ]:        374 :     if (reason >= 0) {
    3742                 :          5 :         COVERAGE_INC(ofproto_dpif_expired);
    3743                 :          5 :         ofproto_rule_expire(&rule->up, reason);
    3744                 :            :     }
    3745                 :        374 : }
    3746                 :            : 
    3747                 :            : static void
    3748                 :       8260 : ofproto_dpif_set_packet_odp_port(const struct ofproto_dpif *ofproto,
    3749                 :            :                                  ofp_port_t in_port, struct dp_packet *packet)
    3750                 :            : {
    3751         [ +  + ]:       8260 :     if (in_port == OFPP_NONE) {
    3752                 :       6551 :         in_port = OFPP_LOCAL;
    3753                 :            :     }
    3754                 :       8260 :     packet->md.in_port.odp_port = ofp_port_to_odp_port(ofproto, in_port);
    3755                 :       8260 : }
    3756                 :            : 
    3757                 :            : int
    3758                 :       8061 : ofproto_dpif_execute_actions__(struct ofproto_dpif *ofproto,
    3759                 :            :                                const struct flow *flow,
    3760                 :            :                                struct rule_dpif *rule,
    3761                 :            :                                const struct ofpact *ofpacts, size_t ofpacts_len,
    3762                 :            :                                int indentation, int depth, int resubmits,
    3763                 :            :                                struct dp_packet *packet)
    3764                 :            : {
    3765                 :            :     struct dpif_flow_stats stats;
    3766                 :            :     struct xlate_out xout;
    3767                 :            :     struct xlate_in xin;
    3768                 :            :     struct dpif_execute execute;
    3769                 :            :     int error;
    3770                 :            : 
    3771         [ -  + ]:       8061 :     ovs_assert((rule != NULL) != (ofpacts != NULL));
    3772                 :            : 
    3773                 :       8061 :     dpif_flow_stats_extract(flow, packet, time_msec(), &stats);
    3774                 :            : 
    3775         [ -  + ]:       8061 :     if (rule) {
    3776                 :          0 :         rule_dpif_credit_stats(rule, &stats);
    3777                 :            :     }
    3778                 :            : 
    3779                 :            :     uint64_t odp_actions_stub[1024 / 8];
    3780                 :       8061 :     struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub);
    3781                 :       8061 :     xlate_in_init(&xin, ofproto, flow, flow->in_port.ofp_port, rule,
    3782                 :       8061 :                   stats.tcp_flags, packet, NULL, &odp_actions);
    3783                 :       8061 :     xin.ofpacts = ofpacts;
    3784                 :       8061 :     xin.ofpacts_len = ofpacts_len;
    3785                 :       8061 :     xin.resubmit_stats = &stats;
    3786                 :       8061 :     xin.indentation = indentation;
    3787                 :       8061 :     xin.depth = depth;
    3788                 :       8061 :     xin.resubmits = resubmits;
    3789         [ -  + ]:       8061 :     if (xlate_actions(&xin, &xout) != XLATE_OK) {
    3790                 :          0 :         error = EINVAL;
    3791                 :          0 :         goto out;
    3792                 :            :     }
    3793                 :            : 
    3794                 :       8061 :     execute.actions = odp_actions.data;
    3795                 :       8061 :     execute.actions_len = odp_actions.size;
    3796                 :            : 
    3797                 :       8061 :     pkt_metadata_from_flow(&packet->md, flow);
    3798                 :       8061 :     execute.packet = packet;
    3799                 :       8061 :     execute.flow = flow;
    3800                 :       8061 :     execute.needs_help = (xout.slow & SLOW_ACTION) != 0;
    3801                 :       8061 :     execute.probe = false;
    3802                 :       8061 :     execute.mtu = 0;
    3803                 :            : 
    3804                 :            :     /* Fix up in_port. */
    3805                 :       8061 :     ofproto_dpif_set_packet_odp_port(ofproto, flow->in_port.ofp_port, packet);
    3806                 :            : 
    3807                 :       8061 :     error = dpif_execute(ofproto->backer->dpif, &execute);
    3808                 :            : out:
    3809                 :       8061 :     xlate_out_uninit(&xout);
    3810                 :       8061 :     ofpbuf_uninit(&odp_actions);
    3811                 :            : 
    3812                 :       8061 :     return error;
    3813                 :            : }
    3814                 :            : 
    3815                 :            : /* Executes, within 'ofproto', the actions in 'rule' or 'ofpacts' on 'packet'.
    3816                 :            :  * 'flow' must reflect the data in 'packet'. */
    3817                 :            : int
    3818                 :       8050 : ofproto_dpif_execute_actions(struct ofproto_dpif *ofproto,
    3819                 :            :                              const struct flow *flow,
    3820                 :            :                              struct rule_dpif *rule,
    3821                 :            :                              const struct ofpact *ofpacts, size_t ofpacts_len,
    3822                 :            :                              struct dp_packet *packet)
    3823                 :            : {
    3824                 :       8050 :     return ofproto_dpif_execute_actions__(ofproto, flow, rule, ofpacts,
    3825                 :            :                                           ofpacts_len, 0, 0, 0, packet);
    3826                 :            : }
    3827                 :            : 
    3828                 :            : static void
    3829                 :     179817 : rule_dpif_credit_stats__(struct rule_dpif *rule,
    3830                 :            :                          const struct dpif_flow_stats *stats,
    3831                 :            :                          bool credit_counts)
    3832                 :            :     OVS_REQUIRES(rule->stats_mutex)
    3833                 :            : {
    3834         [ +  - ]:     179817 :     if (credit_counts) {
    3835                 :     179817 :         rule->stats.n_packets += stats->n_packets;
    3836                 :     179817 :         rule->stats.n_bytes += stats->n_bytes;
    3837                 :            :     }
    3838                 :     179817 :     rule->stats.used = MAX(rule->stats.used, stats->used);
    3839                 :     179817 : }
    3840                 :            : 
    3841                 :            : void
    3842                 :     179817 : rule_dpif_credit_stats(struct rule_dpif *rule,
    3843                 :            :                        const struct dpif_flow_stats *stats)
    3844                 :            : {
    3845                 :     179817 :     ovs_mutex_lock(&rule->stats_mutex);
    3846         [ -  + ]:     179817 :     if (OVS_UNLIKELY(rule->new_rule)) {
    3847                 :          0 :         ovs_mutex_lock(&rule->new_rule->stats_mutex);
    3848                 :          0 :         rule_dpif_credit_stats__(rule->new_rule, stats, rule->forward_counts);
    3849                 :          0 :         ovs_mutex_unlock(&rule->new_rule->stats_mutex);
    3850                 :            :     } else {
    3851                 :     179817 :         rule_dpif_credit_stats__(rule, stats, true);
    3852                 :            :     }
    3853                 :     179817 :     ovs_mutex_unlock(&rule->stats_mutex);
    3854                 :     179817 : }
    3855                 :            : 
    3856                 :            : ovs_be64
    3857                 :    1286678 : rule_dpif_get_flow_cookie(const struct rule_dpif *rule)
    3858                 :            :     OVS_REQUIRES(rule->up.mutex)
    3859                 :            : {
    3860                 :    1286678 :     return rule->up.flow_cookie;
    3861                 :            : }
    3862                 :            : 
    3863                 :            : void
    3864                 :          1 : rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout,
    3865                 :            :                      uint16_t hard_timeout)
    3866                 :            : {
    3867                 :          1 :     ofproto_rule_reduce_timeouts(&rule->up, idle_timeout, hard_timeout);
    3868                 :          1 : }
    3869                 :            : 
    3870                 :            : /* Returns 'rule''s actions.  The returned actions are RCU-protected, and can
    3871                 :            :  * be read until the calling thread quiesces. */
    3872                 :            : const struct rule_actions *
    3873                 :    1294163 : rule_dpif_get_actions(const struct rule_dpif *rule)
    3874                 :            : {
    3875                 :    1294163 :     return rule_get_actions(&rule->up);
    3876                 :            : }
    3877                 :            : 
    3878                 :            : /* Sets 'rule''s recirculation id. */
    3879                 :            : static void
    3880                 :          0 : rule_dpif_set_recirc_id(struct rule_dpif *rule, uint32_t id)
    3881                 :            :     OVS_REQUIRES(rule->up.mutex)
    3882                 :            : {
    3883 [ #  # ][ #  # ]:          0 :     ovs_assert(!rule->recirc_id || rule->recirc_id == id);
    3884         [ #  # ]:          0 :     if (rule->recirc_id == id) {
    3885                 :            :         /* Release the new reference to the same id. */
    3886                 :          0 :         recirc_free_id(id);
    3887                 :            :     } else {
    3888                 :          0 :         rule->recirc_id = id;
    3889                 :            :     }
    3890                 :          0 : }
    3891                 :            : 
    3892                 :            : /* Sets 'rule''s recirculation id. */
    3893                 :            : void
    3894                 :          0 : rule_set_recirc_id(struct rule *rule_, uint32_t id)
    3895                 :            : {
    3896                 :          0 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    3897                 :            : 
    3898                 :          0 :     ovs_mutex_lock(&rule->up.mutex);
    3899                 :          0 :     rule_dpif_set_recirc_id(rule, id);
    3900                 :          0 :     ovs_mutex_unlock(&rule->up.mutex);
    3901                 :          0 : }
    3902                 :            : 
    3903                 :            : ovs_version_t
    3904                 :     124615 : ofproto_dpif_get_tables_version(struct ofproto_dpif *ofproto OVS_UNUSED)
    3905                 :            : {
    3906                 :            :     ovs_version_t version;
    3907                 :            : 
    3908                 :     124615 :     atomic_read_relaxed(&ofproto->tables_version, &version);
    3909                 :            : 
    3910                 :     124615 :     return version;
    3911                 :            : }
    3912                 :            : 
    3913                 :            : /* The returned rule (if any) is valid at least until the next RCU quiescent
    3914                 :            :  * period.  If the rule needs to stay around longer, the caller should take
    3915                 :            :  * a reference.
    3916                 :            :  *
    3917                 :            :  * 'flow' is non-const to allow for temporary modifications during the lookup.
    3918                 :            :  * Any changes are restored before returning. */
    3919                 :            : static struct rule_dpif *
    3920                 :    1293596 : rule_dpif_lookup_in_table(struct ofproto_dpif *ofproto, ovs_version_t version,
    3921                 :            :                           uint8_t table_id, struct flow *flow,
    3922                 :            :                           struct flow_wildcards *wc)
    3923                 :            : {
    3924                 :    1293596 :     struct classifier *cls = &ofproto->up.tables[table_id].cls;
    3925                 :    1293596 :     return rule_dpif_cast(rule_from_cls_rule(classifier_lookup(cls, version,
    3926                 :            :                                                                flow, wc)));
    3927                 :            : }
    3928                 :            : 
    3929                 :            : /* Look up 'flow' in 'ofproto''s classifier version 'version', starting from
    3930                 :            :  * table '*table_id'.  Returns the rule that was found, which may be one of the
    3931                 :            :  * special rules according to packet miss hadling.  If 'may_packet_in' is
    3932                 :            :  * false, returning of the miss_rule (which issues packet ins for the
    3933                 :            :  * controller) is avoided.  Updates 'wc', if nonnull, to reflect the fields
    3934                 :            :  * that were used during the lookup.
    3935                 :            :  *
    3936                 :            :  * If 'honor_table_miss' is true, the first lookup occurs in '*table_id', but
    3937                 :            :  * if none is found then the table miss configuration for that table is
    3938                 :            :  * honored, which can result in additional lookups in other OpenFlow tables.
    3939                 :            :  * In this case the function updates '*table_id' to reflect the final OpenFlow
    3940                 :            :  * table that was searched.
    3941                 :            :  *
    3942                 :            :  * If 'honor_table_miss' is false, then only one table lookup occurs, in
    3943                 :            :  * '*table_id'.
    3944                 :            :  *
    3945                 :            :  * The rule is returned in '*rule', which is valid at least until the next
    3946                 :            :  * RCU quiescent period.  If the '*rule' needs to stay around longer, the
    3947                 :            :  * caller must take a reference.
    3948                 :            :  *
    3949                 :            :  * 'in_port' allows the lookup to take place as if the in port had the value
    3950                 :            :  * 'in_port'.  This is needed for resubmit action support.
    3951                 :            :  *
    3952                 :            :  * 'flow' is non-const to allow for temporary modifications during the lookup.
    3953                 :            :  * Any changes are restored before returning. */
    3954                 :            : struct rule_dpif *
    3955                 :    1286781 : rule_dpif_lookup_from_table(struct ofproto_dpif *ofproto,
    3956                 :            :                             ovs_version_t version, struct flow *flow,
    3957                 :            :                             struct flow_wildcards *wc,
    3958                 :            :                             const struct dpif_flow_stats *stats,
    3959                 :            :                             uint8_t *table_id, ofp_port_t in_port,
    3960                 :            :                             bool may_packet_in, bool honor_table_miss)
    3961                 :            : {
    3962                 :    1286781 :     ovs_be16 old_tp_src = flow->tp_src, old_tp_dst = flow->tp_dst;
    3963                 :    1286781 :     ofp_port_t old_in_port = flow->in_port.ofp_port;
    3964                 :            :     enum ofputil_table_miss miss_config;
    3965                 :            :     struct rule_dpif *rule;
    3966                 :            :     uint8_t next_id;
    3967                 :            : 
    3968                 :            :     /* We always unwildcard nw_frag (for IP), so they
    3969                 :            :      * need not be unwildcarded here. */
    3970         [ +  + ]:    1286781 :     if (flow->nw_frag & FLOW_NW_FRAG_ANY
    3971         [ +  + ]:        209 :         && ofproto->up.frag_handling != OFPUTIL_FRAG_NX_MATCH) {
    3972         [ +  + ]:        205 :         if (ofproto->up.frag_handling == OFPUTIL_FRAG_NORMAL) {
    3973                 :            :             /* We must pretend that transport ports are unavailable. */
    3974                 :        201 :             flow->tp_src = htons(0);
    3975                 :        201 :             flow->tp_dst = htons(0);
    3976                 :            :         } else {
    3977                 :            :             /* Must be OFPUTIL_FRAG_DROP (we don't have OFPUTIL_FRAG_REASM).
    3978                 :            :              * Use the drop_frags_rule (which cannot disappear). */
    3979                 :          4 :             rule = ofproto->drop_frags_rule;
    3980         [ +  + ]:          4 :             if (stats) {
    3981                 :          2 :                 struct oftable *tbl = &ofproto->up.tables[*table_id];
    3982                 :            :                 unsigned long orig;
    3983                 :            : 
    3984                 :          2 :                 atomic_add_relaxed(&tbl->n_matched, stats->n_packets, &orig);
    3985                 :            :             }
    3986                 :          4 :             return rule;
    3987                 :            :         }
    3988                 :            :     }
    3989                 :            : 
    3990                 :            :     /* Look up a flow with 'in_port' as the input port.  Then restore the
    3991                 :            :      * original input port (otherwise OFPP_NORMAL and OFPP_IN_PORT will
    3992                 :            :      * have surprising behavior). */
    3993                 :    1286777 :     flow->in_port.ofp_port = in_port;
    3994                 :            : 
    3995                 :            :     /* Our current implementation depends on n_tables == N_TABLES, and
    3996                 :            :      * TBL_INTERNAL being the last table. */
    3997                 :            :     BUILD_ASSERT_DECL(N_TABLES == TBL_INTERNAL + 1);
    3998                 :            : 
    3999                 :    1286777 :     miss_config = OFPUTIL_TABLE_MISS_CONTINUE;
    4000                 :            : 
    4001         [ +  + ]:    1288817 :     for (next_id = *table_id;
    4002                 :    1288817 :          next_id < ofproto->up.n_tables;
    4003                 :       2040 :          next_id++, next_id += (next_id == TBL_INTERNAL))
    4004                 :            :     {
    4005                 :    1288809 :         *table_id = next_id;
    4006                 :    1288809 :         rule = rule_dpif_lookup_in_table(ofproto, version, next_id, flow, wc);
    4007         [ +  + ]:    1288808 :         if (stats) {
    4008                 :     153383 :             struct oftable *tbl = &ofproto->up.tables[next_id];
    4009                 :            :             unsigned long orig;
    4010                 :            : 
    4011         [ +  + ]:     153383 :             atomic_add_relaxed(rule ? &tbl->n_matched : &tbl->n_missed,
    4012                 :            :                                stats->n_packets, &orig);
    4013                 :            :         }
    4014         [ +  + ]:    1288808 :         if (rule) {
    4015                 :    1279712 :             goto out;   /* Match. */
    4016                 :            :         }
    4017         [ +  + ]:       9096 :         if (honor_table_miss) {
    4018                 :       5948 :             miss_config = ofproto_table_get_miss_config(&ofproto->up,
    4019                 :       5948 :                                                         *table_id);
    4020         [ +  + ]:       5948 :             if (miss_config == OFPUTIL_TABLE_MISS_CONTINUE) {
    4021                 :       2040 :                 continue;
    4022                 :            :             }
    4023                 :            :         }
    4024                 :       7056 :         break;
    4025                 :            :     }
    4026                 :            :     /* Miss. */
    4027                 :       7064 :     rule = ofproto->no_packet_in_rule;
    4028         [ +  + ]:       7064 :     if (may_packet_in) {
    4029         [ +  + ]:       3916 :         if (miss_config == OFPUTIL_TABLE_MISS_CONTINUE
    4030         [ -  + ]:       3916 :             || miss_config == OFPUTIL_TABLE_MISS_CONTROLLER) {
    4031                 :            :             struct ofport_dpif *port;
    4032                 :            : 
    4033                 :          8 :             port = ofp_port_to_ofport(ofproto, old_in_port);
    4034         [ -  + ]:          8 :             if (!port) {
    4035         [ #  # ]:          0 :                 VLOG_WARN_RL(&rl, "packet-in on unknown OpenFlow port %"PRIu16,
    4036                 :            :                              old_in_port);
    4037         [ +  - ]:          8 :             } else if (!(port->up.pp.config & OFPUTIL_PC_NO_PACKET_IN)) {
    4038                 :          8 :                 rule = ofproto->miss_rule;
    4039                 :            :             }
    4040   [ +  +  +  + ]:       7812 :         } else if (miss_config == OFPUTIL_TABLE_MISS_DEFAULT &&
    4041                 :       3904 :                    connmgr_wants_packet_in_on_miss(ofproto->up.connmgr)) {
    4042                 :        134 :             rule = ofproto->miss_rule;
    4043                 :            :         }
    4044                 :            :     }
    4045                 :            : out:
    4046                 :            :     /* Restore port numbers, as they may have been modified above. */
    4047                 :    1286776 :     flow->tp_src = old_tp_src;
    4048                 :    1286776 :     flow->tp_dst = old_tp_dst;
    4049                 :            :     /* Restore the old in port. */
    4050                 :    1286776 :     flow->in_port.ofp_port = old_in_port;
    4051                 :            : 
    4052                 :    1286776 :     return rule;
    4053                 :            : }
    4054                 :            : 
    4055                 :    1436096 : static struct rule_dpif *rule_dpif_cast(const struct rule *rule)
    4056                 :            : {
    4057                 :    1436096 :     return rule ? CONTAINER_OF(rule, struct rule_dpif, up) : NULL;
    4058                 :            : }
    4059                 :            : 
    4060                 :            : static struct rule *
    4061                 :      32020 : rule_alloc(void)
    4062                 :            : {
    4063                 :      32020 :     struct rule_dpif *rule = xzalloc(sizeof *rule);
    4064                 :      32020 :     return &rule->up;
    4065                 :            : }
    4066                 :            : 
    4067                 :            : static void
    4068                 :      28492 : rule_dealloc(struct rule *rule_)
    4069                 :            : {
    4070                 :      28492 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    4071                 :      28492 :     free(rule);
    4072                 :      28492 : }
    4073                 :            : 
    4074                 :            : static enum ofperr
    4075                 :      32020 : check_mask(struct ofproto_dpif *ofproto, const struct miniflow *flow)
    4076                 :            : {
    4077                 :            :     const struct odp_support *support;
    4078                 :            :     uint16_t ct_state, ct_zone;
    4079                 :            :     ovs_u128 ct_label;
    4080                 :            :     uint32_t ct_mark;
    4081                 :            : 
    4082                 :      32020 :     support = &ofproto_dpif_get_support(ofproto)->odp;
    4083         [ +  + ]:      32020 :     ct_state = MINIFLOW_GET_U16(flow, ct_state);
    4084 [ +  - ][ +  - ]:      32020 :     if (support->ct_state && support->ct_zone && support->ct_mark
                 [ +  - ]
    4085 [ +  - ][ +  + ]:      32020 :         && support->ct_label && support->ct_state_nat) {
    4086         [ -  + ]:       3599 :         return ct_state & CS_UNSUPPORTED_MASK ? OFPERR_OFPBMC_BAD_MASK : 0;
    4087                 :            :     }
    4088                 :            : 
    4089         [ +  + ]:      28421 :     ct_zone = MINIFLOW_GET_U16(flow, ct_zone);
    4090         [ +  + ]:      28421 :     ct_mark = MINIFLOW_GET_U32(flow, ct_mark);
    4091 [ +  + ][ +  + ]:      28421 :     ct_label = MINIFLOW_GET_U128(flow, ct_label);
    4092                 :            : 
    4093 [ +  + ][ +  - ]:      28421 :     if ((ct_state && !support->ct_state)
    4094         [ +  - ]:      28421 :         || (ct_state & CS_UNSUPPORTED_MASK)
    4095 [ -  + ][ #  # ]:      28421 :         || ((ct_state & (CS_SRC_NAT | CS_DST_NAT)) && !support->ct_state_nat)
    4096 [ +  + ][ +  - ]:      28421 :         || (ct_zone && !support->ct_zone)
    4097 [ +  + ][ +  - ]:      28421 :         || (ct_mark && !support->ct_mark)
    4098 [ +  + ][ -  + ]:      28421 :         || (!ovs_u128_is_zero(ct_label) && !support->ct_label)) {
    4099                 :          0 :         return OFPERR_OFPBMC_BAD_MASK;
    4100                 :            :     }
    4101                 :            : 
    4102                 :      32020 :     return 0;
    4103                 :            : }
    4104                 :            : 
    4105                 :            : static enum ofperr
    4106                 :      32020 : check_actions(const struct ofproto_dpif *ofproto,
    4107                 :            :               const struct rule_actions *const actions)
    4108                 :            : {
    4109                 :            :     const struct ofpact *ofpact;
    4110                 :            : 
    4111         [ +  + ]:      71701 :     OFPACT_FOR_EACH (ofpact, actions->ofpacts, actions->ofpacts_len) {
    4112                 :            :         const struct odp_support *support;
    4113                 :            :         const struct ofpact_conntrack *ct;
    4114                 :            :         const struct ofpact *a;
    4115                 :            : 
    4116         [ +  + ]:      40239 :         if (ofpact->type != OFPACT_CT) {
    4117                 :      37872 :             continue;
    4118                 :            :         }
    4119                 :            : 
    4120                 :       2367 :         ct = CONTAINER_OF(ofpact, struct ofpact_conntrack, ofpact);
    4121                 :       2367 :         support = &ofproto_dpif_get_support(ofproto)->odp;
    4122                 :            : 
    4123         [ -  + ]:       2367 :         if (!support->ct_state) {
    4124                 :          0 :             return OFPERR_OFPBAC_BAD_TYPE;
    4125                 :            :         }
    4126 [ +  + ][ +  + ]:       2367 :         if ((ct->zone_imm || ct->zone_src.field) && !support->ct_zone) {
                 [ -  + ]
    4127                 :          0 :             return OFPERR_OFPBAC_BAD_ARGUMENT;
    4128                 :            :         }
    4129                 :            : 
    4130         [ +  + ]:       3304 :         OFPACT_FOR_EACH(a, ct->actions, ofpact_ct_get_action_len(ct)) {
    4131                 :       1495 :             const struct mf_field *dst = ofpact_get_mf_dst(a);
    4132                 :            : 
    4133 [ +  + ][ +  + ]:       1495 :             if (a->type == OFPACT_NAT && !support->ct_state_nat) {
    4134                 :            :                 /* The backer doesn't seem to support the NAT bits in
    4135                 :            :                  * 'ct_state': assume that it doesn't support the NAT
    4136                 :            :                  * action. */
    4137                 :        558 :                 return OFPERR_OFPBAC_BAD_TYPE;
    4138                 :            :             }
    4139 [ +  + ][ +  + ]:        937 :             if (dst && ((dst->id == MFF_CT_MARK && !support->ct_mark)
                 [ +  - ]
    4140 [ +  + ][ -  + ]:        748 :                         || (dst->id == MFF_CT_LABEL && !support->ct_label))) {
    4141                 :          0 :                 return OFPERR_OFPBAC_BAD_SET_ARGUMENT;
    4142                 :            :             }
    4143                 :            :         }
    4144                 :            :     }
    4145                 :            : 
    4146                 :      31462 :     return 0;
    4147                 :            : }
    4148                 :            : 
    4149                 :            : static enum ofperr
    4150                 :      32020 : rule_check(struct rule *rule)
    4151                 :            : {
    4152                 :      32020 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(rule->ofproto);
    4153                 :            :     enum ofperr err;
    4154                 :            : 
    4155                 :      32020 :     err = check_mask(ofproto, &rule->cr.match.mask->masks);
    4156         [ -  + ]:      32020 :     if (err) {
    4157                 :          0 :         return err;
    4158                 :            :     }
    4159                 :      32020 :     return check_actions(ofproto, rule->actions);
    4160                 :            : }
    4161                 :            : 
    4162                 :            : static enum ofperr
    4163                 :      32020 : rule_construct(struct rule *rule_)
    4164                 :            :     OVS_NO_THREAD_SAFETY_ANALYSIS
    4165                 :            : {
    4166                 :      32020 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    4167                 :            :     int error;
    4168                 :            : 
    4169                 :      32020 :     error = rule_check(rule_);
    4170         [ +  + ]:      32020 :     if (error) {
    4171                 :        558 :         return error;
    4172                 :            :     }
    4173                 :            : 
    4174                 :      31462 :     ovs_mutex_init_adaptive(&rule->stats_mutex);
    4175                 :      31462 :     rule->stats.n_packets = 0;
    4176                 :      31462 :     rule->stats.n_bytes = 0;
    4177                 :      31462 :     rule->stats.used = rule->up.modified;
    4178                 :      31462 :     rule->recirc_id = 0;
    4179                 :      31462 :     rule->new_rule = NULL;
    4180                 :      31462 :     rule->forward_counts = false;
    4181                 :            : 
    4182                 :      31462 :     return 0;
    4183                 :            : }
    4184                 :            : 
    4185                 :            : static void
    4186                 :      31430 : rule_insert(struct rule *rule_, struct rule *old_rule_, bool forward_counts)
    4187                 :            :     OVS_REQUIRES(ofproto_mutex)
    4188                 :            : {
    4189                 :      31430 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    4190                 :            : 
    4191         [ +  + ]:      31430 :     if (old_rule_) {
    4192                 :        995 :         struct rule_dpif *old_rule = rule_dpif_cast(old_rule_);
    4193                 :            : 
    4194         [ -  + ]:        995 :         ovs_assert(!old_rule->new_rule);
    4195                 :            : 
    4196                 :            :         /* Take a reference to the new rule, and refer all stats updates from
    4197                 :            :          * the old rule to the new rule. */
    4198                 :        995 :         rule_dpif_ref(rule);
    4199                 :            : 
    4200                 :        995 :         ovs_mutex_lock(&old_rule->stats_mutex);
    4201                 :        995 :         ovs_mutex_lock(&rule->stats_mutex);
    4202                 :        995 :         old_rule->new_rule = rule;       /* Forward future stats. */
    4203                 :        995 :         old_rule->forward_counts = forward_counts;
    4204                 :            : 
    4205         [ +  + ]:        995 :         if (forward_counts) {
    4206                 :        879 :             rule->stats = old_rule->stats;   /* Transfer stats to the new
    4207                 :            :                                               * rule. */
    4208                 :            :         } else {
    4209                 :            :             /* Used timestamp must be forwarded whenever a rule is modified. */
    4210                 :        116 :             rule->stats.used = old_rule->stats.used;
    4211                 :            :         }
    4212                 :        995 :         ovs_mutex_unlock(&rule->stats_mutex);
    4213                 :        995 :         ovs_mutex_unlock(&old_rule->stats_mutex);
    4214                 :            :     }
    4215                 :      31430 : }
    4216                 :            : 
    4217                 :            : static void
    4218                 :      27934 : rule_destruct(struct rule *rule_)
    4219                 :            :     OVS_NO_THREAD_SAFETY_ANALYSIS
    4220                 :            : {
    4221                 :      27934 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    4222                 :            : 
    4223                 :      27934 :     ovs_mutex_destroy(&rule->stats_mutex);
    4224                 :            :     /* Release reference to the new rule, if any. */
    4225         [ +  + ]:      27934 :     if (rule->new_rule) {
    4226                 :        995 :         rule_dpif_unref(rule->new_rule);
    4227                 :            :     }
    4228         [ -  + ]:      27934 :     if (rule->recirc_id) {
    4229                 :          0 :         recirc_free_id(rule->recirc_id);
    4230                 :            :     }
    4231                 :      27934 : }
    4232                 :            : 
    4233                 :            : static void
    4234                 :      19009 : rule_get_stats(struct rule *rule_, uint64_t *packets, uint64_t *bytes,
    4235                 :            :                long long int *used)
    4236                 :            : {
    4237                 :      19009 :     struct rule_dpif *rule = rule_dpif_cast(rule_);
    4238                 :            : 
    4239                 :      19009 :     ovs_mutex_lock(&rule->stats_mutex);
    4240         [ -  + ]:      19009 :     if (OVS_UNLIKELY(rule->new_rule)) {
    4241                 :          0 :         rule_get_stats(&rule->new_rule->up, packets, bytes, used);
    4242                 :            :     } else {
    4243                 :      19009 :         *packets = rule->stats.n_packets;
    4244                 :      19009 :         *bytes = rule->stats.n_bytes;
    4245                 :      19009 :         *used = rule->stats.used;
    4246                 :            :     }
    4247                 :      19009 :     ovs_mutex_unlock(&rule->stats_mutex);
    4248                 :      19009 : }
    4249                 :            : 
    4250                 :        526 : static struct group_dpif *group_dpif_cast(const struct ofgroup *group)
    4251                 :            : {
    4252                 :        526 :     return group ? CONTAINER_OF(group, struct group_dpif, up) : NULL;
    4253                 :            : }
    4254                 :            : 
    4255                 :            : static struct ofgroup *
    4256                 :        103 : group_alloc(void)
    4257                 :            : {
    4258                 :        103 :     struct group_dpif *group = xzalloc(sizeof *group);
    4259                 :        103 :     return &group->up;
    4260                 :            : }
    4261                 :            : 
    4262                 :            : static void
    4263                 :         74 : group_dealloc(struct ofgroup *group_)
    4264                 :            : {
    4265                 :         74 :     struct group_dpif *group = group_dpif_cast(group_);
    4266                 :         74 :     free(group);
    4267                 :         74 : }
    4268                 :            : 
    4269                 :            : static void
    4270                 :        103 : group_construct_stats(struct group_dpif *group)
    4271                 :            :     OVS_REQUIRES(group->stats_mutex)
    4272                 :            : {
    4273                 :            :     struct ofputil_bucket *bucket;
    4274                 :            :     const struct ovs_list *buckets;
    4275                 :            : 
    4276                 :        103 :     group->packet_count = 0;
    4277                 :        103 :     group->byte_count = 0;
    4278                 :            : 
    4279                 :        103 :     buckets = group_dpif_get_buckets(group);
    4280         [ +  + ]:        238 :     LIST_FOR_EACH (bucket, list_node, buckets) {
    4281                 :        135 :         bucket->stats.packet_count = 0;
    4282                 :        135 :         bucket->stats.byte_count = 0;
    4283                 :            :     }
    4284                 :        103 : }
    4285                 :            : 
    4286                 :            : void
    4287                 :        245 : group_dpif_credit_stats(struct group_dpif *group,
    4288                 :            :                         struct ofputil_bucket *bucket,
    4289                 :            :                         const struct dpif_flow_stats *stats)
    4290                 :            : {
    4291                 :        245 :     ovs_mutex_lock(&group->stats_mutex);
    4292                 :        245 :     group->packet_count += stats->n_packets;
    4293                 :        245 :     group->byte_count += stats->n_bytes;
    4294         [ +  + ]:        245 :     if (bucket) {
    4295                 :        241 :         bucket->stats.packet_count += stats->n_packets;
    4296                 :        241 :         bucket->stats.byte_count += stats->n_bytes;
    4297                 :            :     } else { /* Credit to all buckets */
    4298                 :            :         const struct ovs_list *buckets;
    4299                 :            : 
    4300                 :          4 :         buckets = group_dpif_get_buckets(group);
    4301         [ +  + ]:         12 :         LIST_FOR_EACH (bucket, list_node, buckets) {
    4302                 :          8 :             bucket->stats.packet_count += stats->n_packets;
    4303                 :          8 :             bucket->stats.byte_count += stats->n_bytes;
    4304                 :            :         }
    4305                 :            :     }
    4306                 :        245 :     ovs_mutex_unlock(&group->stats_mutex);
    4307                 :        245 : }
    4308                 :            : 
    4309                 :            : static enum ofperr
    4310                 :        103 : group_construct(struct ofgroup *group_)
    4311                 :            : {
    4312                 :        103 :     struct group_dpif *group = group_dpif_cast(group_);
    4313                 :            : 
    4314                 :        103 :     ovs_mutex_init_adaptive(&group->stats_mutex);
    4315                 :        103 :     ovs_mutex_lock(&group->stats_mutex);
    4316                 :        103 :     group_construct_stats(group);
    4317                 :        103 :     ovs_mutex_unlock(&group->stats_mutex);
    4318                 :        103 :     return 0;
    4319                 :            : }
    4320                 :            : 
    4321                 :            : static void
    4322                 :         74 : group_destruct(struct ofgroup *group_)
    4323                 :            : {
    4324                 :         74 :     struct group_dpif *group = group_dpif_cast(group_);
    4325                 :         74 :     ovs_mutex_destroy(&group->stats_mutex);
    4326                 :         74 : }
    4327                 :            : 
    4328                 :            : static void
    4329                 :         31 : group_modify(struct ofgroup *group_)
    4330                 :            : {
    4331                 :         31 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(group_->ofproto);
    4332                 :            : 
    4333                 :         31 :     ofproto->backer->need_revalidate = REV_FLOW_TABLE;
    4334                 :         31 : }
    4335                 :            : 
    4336                 :            : static enum ofperr
    4337                 :         11 : group_get_stats(const struct ofgroup *group_, struct ofputil_group_stats *ogs)
    4338                 :            : {
    4339                 :         11 :     struct group_dpif *group = group_dpif_cast(group_);
    4340                 :            :     struct ofputil_bucket *bucket;
    4341                 :            :     const struct ovs_list *buckets;
    4342                 :            :     struct bucket_counter *bucket_stats;
    4343                 :            : 
    4344                 :         11 :     ovs_mutex_lock(&group->stats_mutex);
    4345                 :         11 :     ogs->packet_count = group->packet_count;
    4346                 :         11 :     ogs->byte_count = group->byte_count;
    4347                 :            : 
    4348                 :         11 :     buckets = group_dpif_get_buckets(group);
    4349                 :         11 :     bucket_stats = ogs->bucket_stats;
    4350         [ +  + ]:         26 :     LIST_FOR_EACH (bucket, list_node, buckets) {
    4351                 :         15 :         bucket_stats->packet_count = bucket->stats.packet_count;
    4352                 :         15 :         bucket_stats->byte_count = bucket->stats.byte_count;
    4353                 :         15 :         bucket_stats++;
    4354                 :            :     }
    4355                 :         11 :     ovs_mutex_unlock(&group->stats_mutex);
    4356                 :            : 
    4357                 :         11 :     return 0;
    4358                 :            : }
    4359                 :            : 
    4360                 :            : /* If the group exists, this function increments the groups's reference count.
    4361                 :            :  *
    4362                 :            :  * Make sure to call group_dpif_unref() after no longer needing to maintain
    4363                 :            :  * a reference to the group. */
    4364                 :            : struct group_dpif *
    4365                 :        264 : group_dpif_lookup(struct ofproto_dpif *ofproto, uint32_t group_id,
    4366                 :            :                   ovs_version_t version, bool take_ref)
    4367                 :            : {
    4368                 :        264 :     struct ofgroup *ofgroup = ofproto_group_lookup(&ofproto->up, group_id,
    4369                 :            :                                                    version, take_ref);
    4370         [ +  - ]:        264 :     return ofgroup ? group_dpif_cast(ofgroup) : NULL;
    4371                 :            : }
    4372                 :            : 
    4373                 :            : const struct ovs_list *
    4374                 :        382 : group_dpif_get_buckets(const struct group_dpif *group)
    4375                 :            : {
    4376                 :        382 :     return &group->up.buckets;
    4377                 :            : }
    4378                 :            : 
    4379                 :            : enum ofp11_group_type
    4380                 :        264 : group_dpif_get_type(const struct group_dpif *group)
    4381                 :            : {
    4382                 :        264 :     return group->up.type;
    4383                 :            : }
    4384                 :            : 
    4385                 :            : const char *
    4386                 :        250 : group_dpif_get_selection_method(const struct group_dpif *group)
    4387                 :            : {
    4388                 :        250 :     return group->up.props.selection_method;
    4389                 :            : }
    4390                 :            : 
    4391                 :            : /* Sends 'packet' out 'ofport'. If 'port' is a tunnel and that tunnel type
    4392                 :            :  * supports a notion of an OAM flag, sets it if 'oam' is true.
    4393                 :            :  * May modify 'packet'.
    4394                 :            :  * Returns 0 if successful, otherwise a positive errno value. */
    4395                 :            : int
    4396                 :       6534 : ofproto_dpif_send_packet(const struct ofport_dpif *ofport, bool oam,
    4397                 :            :                          struct dp_packet *packet)
    4398                 :            : {
    4399                 :       6534 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
    4400                 :            :     int error;
    4401                 :            : 
    4402                 :       6534 :     error = xlate_send_packet(ofport, oam, packet);
    4403                 :            : 
    4404                 :       6534 :     ovs_mutex_lock(&ofproto->stats_mutex);
    4405                 :       6534 :     ofproto->stats.tx_packets++;
    4406                 :       6534 :     ofproto->stats.tx_bytes += dp_packet_size(packet);
    4407                 :       6534 :     ovs_mutex_unlock(&ofproto->stats_mutex);
    4408                 :       6534 :     return error;
    4409                 :            : }
    4410                 :            : 
    4411                 :            : uint64_t
    4412                 :          0 : group_dpif_get_selection_method_param(const struct group_dpif *group)
    4413                 :            : {
    4414                 :          0 :     return group->up.props.selection_method_param;
    4415                 :            : }
    4416                 :            : 
    4417                 :            : const struct field_array *
    4418                 :          0 : group_dpif_get_fields(const struct group_dpif *group)
    4419                 :            : {
    4420                 :          0 :     return &group->up.props.fields;
    4421                 :            : }
    4422                 :            : 
    4423                 :            : /* Return the version string of the datapath that backs up
    4424                 :            :  * this 'ofproto'.
    4425                 :            :  */
    4426                 :            : static const char *
    4427                 :       6579 : get_datapath_version(const struct ofproto *ofproto_)
    4428                 :            : {
    4429                 :       6579 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4430                 :            : 
    4431                 :       6579 :     return ofproto->backer->dp_version_string;
    4432                 :            : }
    4433                 :            : 
    4434                 :            : static bool
    4435                 :          4 : set_frag_handling(struct ofproto *ofproto_,
    4436                 :            :                   enum ofputil_frag_handling frag_handling)
    4437                 :            : {
    4438                 :          4 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4439         [ +  - ]:          4 :     if (frag_handling != OFPUTIL_FRAG_REASM) {
    4440                 :          4 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    4441                 :          4 :         return true;
    4442                 :            :     } else {
    4443                 :          0 :         return false;
    4444                 :            :     }
    4445                 :            : }
    4446                 :            : 
    4447                 :            : static enum ofperr
    4448                 :       1562 : packet_out(struct ofproto *ofproto_, struct dp_packet *packet,
    4449                 :            :            const struct flow *flow,
    4450                 :            :            const struct ofpact *ofpacts, size_t ofpacts_len)
    4451                 :            : {
    4452                 :       1562 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4453                 :            : 
    4454                 :       1562 :     ofproto_dpif_execute_actions(ofproto, flow, NULL, ofpacts,
    4455                 :            :                                  ofpacts_len, packet);
    4456                 :       1562 :     return 0;
    4457                 :            : }
    4458                 :            : 
    4459                 :            : static enum ofperr
    4460                 :        199 : nxt_resume(struct ofproto *ofproto_,
    4461                 :            :            const struct ofputil_packet_in_private *pin)
    4462                 :            : {
    4463                 :        199 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4464                 :            : 
    4465                 :            :     /* Translate pin into datapath actions. */
    4466                 :            :     uint64_t odp_actions_stub[1024 / 8];
    4467                 :        199 :     struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub);
    4468                 :            :     enum slow_path_reason slow;
    4469                 :        199 :     enum ofperr error = xlate_resume(ofproto, pin, &odp_actions, &slow);
    4470                 :            : 
    4471                 :            :     /* Steal 'pin->packet' and put it into a dp_packet. */
    4472                 :            :     struct dp_packet packet;
    4473                 :        199 :     dp_packet_init(&packet, pin->public.packet_len);
    4474                 :        199 :     dp_packet_put(&packet, pin->public.packet, pin->public.packet_len);
    4475                 :            : 
    4476                 :        199 :     pkt_metadata_from_flow(&packet.md, &pin->public.flow_metadata.flow);
    4477                 :            : 
    4478                 :            :     /* Fix up in_port. */
    4479                 :        199 :     ofproto_dpif_set_packet_odp_port(ofproto,
    4480                 :            :                                      pin->public.flow_metadata.flow.in_port.ofp_port,
    4481                 :            :                                      &packet);
    4482                 :            : 
    4483                 :            :     struct flow headers;
    4484                 :        199 :     flow_extract(&packet, &headers);
    4485                 :            : 
    4486                 :            :     /* Execute the datapath actions on the packet. */
    4487                 :        796 :     struct dpif_execute execute = {
    4488                 :        199 :         .actions = odp_actions.data,
    4489                 :        199 :         .actions_len = odp_actions.size,
    4490                 :        199 :         .needs_help = (slow & SLOW_ACTION) != 0,
    4491                 :            :         .packet = &packet,
    4492                 :            :         .flow = &headers,
    4493                 :            :     };
    4494                 :        199 :     dpif_execute(ofproto->backer->dpif, &execute);
    4495                 :            : 
    4496                 :            :     /* Clean up. */
    4497                 :        199 :     ofpbuf_uninit(&odp_actions);
    4498                 :        199 :     dp_packet_uninit(&packet);
    4499                 :            : 
    4500                 :        199 :     return error;
    4501                 :            : }
    4502                 :            : 
    4503                 :            : /* NetFlow. */
    4504                 :            : 
    4505                 :            : static int
    4506                 :       4700 : set_netflow(struct ofproto *ofproto_,
    4507                 :            :             const struct netflow_options *netflow_options)
    4508                 :            : {
    4509                 :       4700 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4510                 :            : 
    4511         [ +  + ]:       4700 :     if (netflow_options) {
    4512         [ +  - ]:          6 :         if (!ofproto->netflow) {
    4513                 :          6 :             ofproto->netflow = netflow_create();
    4514                 :          6 :             ofproto->backer->need_revalidate = REV_RECONFIGURE;
    4515                 :            :         }
    4516                 :          6 :         return netflow_set_options(ofproto->netflow, netflow_options);
    4517         [ -  + ]:       4694 :     } else if (ofproto->netflow) {
    4518                 :          0 :         ofproto->backer->need_revalidate = REV_RECONFIGURE;
    4519                 :          0 :         netflow_unref(ofproto->netflow);
    4520                 :          0 :         ofproto->netflow = NULL;
    4521                 :            :     }
    4522                 :            : 
    4523                 :       4694 :     return 0;
    4524                 :            : }
    4525                 :            : 
    4526                 :            : static void
    4527                 :          6 : get_netflow_ids(const struct ofproto *ofproto_,
    4528                 :            :                 uint8_t *engine_type, uint8_t *engine_id)
    4529                 :            : {
    4530                 :          6 :     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
    4531                 :            : 
    4532                 :          6 :     dpif_get_netflow_ids(ofproto->backer->dpif, engine_type, engine_id);
    4533                 :          6 : }
    4534                 :            : 
    4535                 :            : static struct ofproto_dpif *
    4536                 :        602 : ofproto_dpif_lookup(const char *name)
    4537                 :            : {
    4538                 :            :     struct ofproto_dpif *ofproto;
    4539                 :            : 
    4540 [ +  + ][ -  + ]:        602 :     HMAP_FOR_EACH_WITH_HASH (ofproto, all_ofproto_dpifs_node,
    4541                 :            :                              hash_string(name, 0), &all_ofproto_dpifs) {
    4542         [ +  - ]:        599 :         if (!strcmp(ofproto->up.name, name)) {
    4543                 :        599 :             return ofproto;
    4544                 :            :         }
    4545                 :            :     }
    4546                 :          3 :     return NULL;
    4547                 :            : }
    4548                 :            : 
    4549                 :            : static void
    4550                 :          0 : ofproto_unixctl_fdb_flush(struct unixctl_conn *conn, int argc,
    4551                 :            :                           const char *argv[], void *aux OVS_UNUSED)
    4552                 :            : {
    4553                 :            :     struct ofproto_dpif *ofproto;
    4554                 :            : 
    4555         [ #  # ]:          0 :     if (argc > 1) {
    4556                 :          0 :         ofproto = ofproto_dpif_lookup(argv[1]);
    4557         [ #  # ]:          0 :         if (!ofproto) {
    4558                 :          0 :             unixctl_command_reply_error(conn, "no such bridge");
    4559                 :          0 :             return;
    4560                 :            :         }
    4561                 :          0 :         ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    4562                 :          0 :         mac_learning_flush(ofproto->ml);
    4563                 :          0 :         ovs_rwlock_unlock(&ofproto->ml->rwlock);
    4564                 :            :     } else {
    4565 [ #  # ][ #  # ]:          0 :         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
    4566                 :          0 :             ovs_rwlock_wrlock(&ofproto->ml->rwlock);
    4567                 :          0 :             mac_learning_flush(ofproto->ml);
    4568                 :          0 :             ovs_rwlock_unlock(&ofproto->ml->rwlock);
    4569                 :            :         }
    4570                 :            :     }
    4571                 :            : 
    4572                 :          0 :     unixctl_command_reply(conn, "table successfully flushed");
    4573                 :            : }
    4574                 :            : 
    4575                 :            : static void
    4576                 :          0 : ofproto_unixctl_mcast_snooping_flush(struct unixctl_conn *conn, int argc,
    4577                 :            :                                      const char *argv[], void *aux OVS_UNUSED)
    4578                 :            : {
    4579                 :            :     struct ofproto_dpif *ofproto;
    4580                 :            : 
    4581         [ #  # ]:          0 :     if (argc > 1) {
    4582                 :          0 :         ofproto = ofproto_dpif_lookup(argv[1]);
    4583         [ #  # ]:          0 :         if (!ofproto) {
    4584                 :          0 :             unixctl_command_reply_error(conn, "no such bridge");
    4585                 :          0 :             return;
    4586                 :            :         }
    4587                 :            : 
    4588         [ #  # ]:          0 :         if (!mcast_snooping_enabled(ofproto->ms)) {
    4589                 :          0 :             unixctl_command_reply_error(conn, "multicast snooping is disabled");
    4590                 :          0 :             return;
    4591                 :            :         }
    4592                 :          0 :         mcast_snooping_mdb_flush(ofproto->ms);
    4593                 :            :     } else {
    4594 [ #  # ][ #  # ]:          0 :         HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
    4595         [ #  # ]:          0 :             if (!mcast_snooping_enabled(ofproto->ms)) {
    4596                 :          0 :                 continue;
    4597                 :            :             }
    4598                 :          0 :             mcast_snooping_mdb_flush(ofproto->ms);
    4599                 :            :         }
    4600                 :            :     }
    4601                 :            : 
    4602                 :          0 :     unixctl_command_reply(conn, "table successfully flushed");
    4603                 :            : }
    4604                 :            : 
    4605                 :            : static struct ofport_dpif *
    4606                 :         55 : ofbundle_get_a_port(const struct ofbundle *bundle)
    4607                 :            : {
    4608                 :         55 :     return CONTAINER_OF(ovs_list_front(&bundle->ports), struct ofport_dpif,
    4609                 :            :                         bundle_node);
    4610                 :            : }
    4611                 :            : 
    4612                 :            : static void
    4613                 :         15 : ofproto_unixctl_fdb_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
    4614                 :            :                          const char *argv[], void *aux OVS_UNUSED)
    4615                 :            : {
    4616                 :         15 :     struct ds ds = DS_EMPTY_INITIALIZER;
    4617                 :            :     const struct ofproto_dpif *ofproto;
    4618                 :            :     const struct mac_entry *e;
    4619                 :            : 
    4620                 :         15 :     ofproto = ofproto_dpif_lookup(argv[1]);
    4621         [ -  + ]:         15 :     if (!ofproto) {
    4622                 :          0 :         unixctl_command_reply_error(conn, "no such bridge");
    4623                 :          0 :         return;
    4624                 :            :     }
    4625                 :            : 
    4626                 :         15 :     ds_put_cstr(&ds, " port  VLAN  MAC                Age\n");
    4627                 :         15 :     ovs_rwlock_rdlock(&ofproto->ml->rwlock);
    4628         [ +  + ]:         70 :     LIST_FOR_EACH (e, lru_node, &ofproto->ml->lrus) {
    4629                 :         55 :         struct ofbundle *bundle = mac_entry_get_port(ofproto->ml, e);
    4630                 :            :         char name[OFP_MAX_PORT_NAME_LEN];
    4631                 :            : 
    4632                 :         55 :         ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
    4633                 :            :                                name, sizeof name);
    4634                 :         55 :         ds_put_format(&ds, "%5s  %4d  "ETH_ADDR_FMT"  %3d\n",
    4635                 :        385 :                       name, e->vlan, ETH_ADDR_ARGS(e->mac),
    4636                 :         55 :                       mac_entry_age(ofproto->ml, e));
    4637                 :            :     }
    4638                 :         15 :     ovs_rwlock_unlock(&ofproto->ml->rwlock);
    4639                 :         15 :     unixctl_command_reply(conn, ds_cstr(&ds));
    4640                 :         15 :     ds_destroy(&ds);
    4641                 :            : }
    4642                 :            : 
    4643                 :            : static void
    4644                 :          0 : ofproto_unixctl_mcast_snooping_show(struct unixctl_conn *conn,
    4645                 :            :                                     int argc OVS_UNUSED,
    4646                 :            :                                     const char *argv[],
    4647                 :            :                                     void *aux OVS_UNUSED)
    4648                 :            : {
    4649                 :          0 :     struct ds ds = DS_EMPTY_INITIALIZER;
    4650                 :            :     const struct ofproto_dpif *ofproto;
    4651                 :            :     const struct ofbundle *bundle;
    4652                 :            :     const struct mcast_group *grp;
    4653                 :            :     struct mcast_group_bundle *b;
    4654                 :            :     struct mcast_mrouter_bundle *mrouter;
    4655                 :            : 
    4656                 :          0 :     ofproto = ofproto_dpif_lookup(argv[1]);
    4657         [ #  # ]:          0 :     if (!ofproto) {
    4658                 :          0 :         unixctl_command_reply_error(conn, "no such bridge");
    4659                 :          0 :         return;
    4660                 :            :     }
    4661                 :            : 
    4662         [ #  # ]:          0 :     if (!mcast_snooping_enabled(ofproto->ms)) {
    4663                 :          0 :         unixctl_command_reply_error(conn, "multicast snooping is disabled");
    4664                 :          0 :         return;
    4665                 :            :     }
    4666                 :            : 
    4667                 :          0 :     ds_put_cstr(&ds, " port  VLAN  GROUP                Age\n");
    4668                 :          0 :     ovs_rwlock_rdlock(&ofproto->ms->rwlock);
    4669         [ #  # ]:          0 :     LIST_FOR_EACH (grp, group_node, &ofproto->ms->group_lru) {
    4670         [ #  # ]:          0 :         LIST_FOR_EACH(b, bundle_node, &grp->bundle_lru) {
    4671                 :            :             char name[OFP_MAX_PORT_NAME_LEN];
    4672                 :            : 
    4673                 :          0 :             bundle = b->port;
    4674                 :          0 :             ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
    4675                 :            :                                    name, sizeof name);
    4676                 :          0 :             ds_put_format(&ds, "%5s  %4d  ", name, grp->vlan);
    4677                 :          0 :             ipv6_format_mapped(&grp->addr, &ds);
    4678                 :          0 :             ds_put_format(&ds, "         %3d\n",
    4679                 :          0 :                           mcast_bundle_age(ofproto->ms, b));
    4680                 :            :         }
    4681                 :            :     }
    4682                 :            : 
    4683                 :            :     /* ports connected to multicast routers */
    4684         [ #  # ]:          0 :     LIST_FOR_EACH(mrouter, mrouter_node, &ofproto->ms->mrouter_lru) {
    4685                 :            :         char name[OFP_MAX_PORT_NAME_LEN];
    4686                 :            : 
    4687                 :          0 :         bundle = mrouter->port;
    4688                 :          0 :         ofputil_port_to_string(ofbundle_get_a_port(bundle)->up.ofp_port,
    4689                 :            :                                name, sizeof name);
    4690                 :          0 :         ds_put_format(&ds, "%5s  %4d  querier             %3d\n",
    4691                 :          0 :                       name, mrouter->vlan,
    4692                 :          0 :                       mcast_mrouter_age(ofproto->ms, mrouter));
    4693                 :            :     }
    4694                 :          0 :     ovs_rwlock_unlock(&ofproto->ms->rwlock);
    4695                 :          0 :     unixctl_command_reply(conn, ds_cstr(&ds));
    4696                 :          0 :     ds_destroy(&ds);
    4697                 :            : }
    4698                 :            : 
    4699                 :            : struct trace_ctx {
    4700                 :            :     struct xlate_out xout;
    4701                 :            :     struct xlate_in xin;
    4702                 :            :     const struct flow *key;
    4703                 :            :     struct flow flow;
    4704                 :            :     struct ds *result;
    4705                 :            :     struct flow_wildcards wc;
    4706                 :            :     struct ofpbuf odp_actions;
    4707                 :            : };
    4708                 :            : 
    4709                 :            : static void
    4710                 :       7485 : trace_format_rule(struct ds *result, int level, const struct rule_dpif *rule)
    4711                 :            : {
    4712                 :            :     const struct rule_actions *actions;
    4713                 :            :     ovs_be64 cookie;
    4714                 :            : 
    4715                 :       7485 :     ds_put_char_multiple(result, '\t', level);
    4716         [ -  + ]:       7485 :     if (!rule) {
    4717                 :          0 :         ds_put_cstr(result, "No match\n");
    4718                 :          0 :         return;
    4719                 :            :     }
    4720                 :            : 
    4721                 :       7485 :     ovs_mutex_lock(&rule->up.mutex);
    4722                 :       7485 :     cookie = rule->up.flow_cookie;
    4723                 :       7485 :     ovs_mutex_unlock(&rule->up.mutex);
    4724                 :            : 
    4725         [ +  - ]:       7485 :     ds_put_format(result, "Rule: table=%"PRIu8" cookie=%#"PRIx64" ",
    4726                 :       7485 :                   rule ? rule->up.table_id : 0, ntohll(cookie));
    4727                 :       7485 :     cls_rule_format(&rule->up.cr, result);
    4728                 :       7485 :     ds_put_char(result, '\n');
    4729                 :            : 
    4730                 :       7485 :     actions = rule_dpif_get_actions(rule);
    4731                 :            : 
    4732                 :       7485 :     ds_put_char_multiple(result, '\t', level);
    4733                 :       7485 :     ds_put_cstr(result, "OpenFlow actions=");
    4734                 :       7485 :     ofpacts_format(actions->ofpacts, actions->ofpacts_len, result);
    4735                 :       7485 :     ds_put_char(result, '\n');
    4736                 :            : }
    4737                 :            : 
    4738                 :            : static void
    4739                 :       7493 : trace_format_flow(struct ds *result, int level, const char *title,
    4740                 :            :                   struct trace_ctx *trace)
    4741                 :            : {
    4742                 :       7493 :     ds_put_char_multiple(result, '\t', level);
    4743                 :       7493 :     ds_put_format(result, "%s: ", title);
    4744                 :            :     /* Do not report unchanged flows for resubmits. */
    4745 [ +  + ][ +  + ]:       7493 :     if ((level > 0 && flow_equal(&trace->xin.flow, &trace->flow))
    4746 [ +  + ][ +  + ]:        999 :         || (level == 0 && flow_equal(&trace->xin.flow, trace->key))) {
    4747                 :       7317 :         ds_put_cstr(result, "unchanged");
    4748                 :            :     } else {
    4749                 :        176 :         flow_format(result, &trace->xin.flow);
    4750                 :        176 :         trace->flow = trace->xin.flow;
    4751                 :            :     }
    4752                 :       7493 :     ds_put_char(result, '\n');
    4753                 :       7493 : }
    4754                 :            : 
    4755                 :            : static void
    4756                 :       6612 : trace_format_regs(struct ds *result, int level, const char *title,
    4757                 :            :                   struct trace_ctx *trace)
    4758                 :            : {
    4759                 :            :     size_t i;
    4760                 :            : 
    4761                 :       6612 :     ds_put_char_multiple(result, '\t', level);
    4762                 :       6612 :     ds_put_format(result, "%s:", title);
    4763         [ +  + ]:     112404 :     for (i = 0; i < FLOW_N_REGS; i++) {
    4764                 :     105792 :         ds_put_format(result, " reg%"PRIuSIZE"=0x%"PRIx32, i, trace->flow.regs[i]);
    4765                 :            :     }
    4766                 :       6612 :     ds_put_char(result, '\n');
    4767                 :       6612 : }
    4768                 :            : 
    4769                 :            : static void
    4770                 :       6612 : trace_format_odp(struct ds *result, int level, const char *title,
    4771                 :            :                  struct trace_ctx *trace)
    4772                 :            : {
    4773                 :       6612 :     struct ofpbuf *odp_actions = &trace->odp_actions;
    4774                 :            : 
    4775                 :       6612 :     ds_put_char_multiple(result, '\t', level);
    4776                 :       6612 :     ds_put_format(result, "%s: ", title);
    4777                 :       6612 :     format_odp_actions(result, odp_actions->data, odp_actions->size);
    4778                 :       6612 :     ds_put_char(result, '\n');
    4779                 :       6612 : }
    4780                 :            : 
    4781                 :            : static void
    4782                 :       7493 : trace_format_megaflow(struct ds *result, int level, const char *title,
    4783                 :            :                       struct trace_ctx *trace)
    4784                 :            : {
    4785                 :            :     struct match match;
    4786                 :            : 
    4787                 :       7493 :     ds_put_char_multiple(result, '\t', level);
    4788                 :       7493 :     ds_put_format(result, "%s: ", title);
    4789                 :       7493 :     match_init(&match, trace->key, &trace->wc);
    4790                 :       7493 :     match_format(&match, result, OFP_DEFAULT_PRIORITY);
    4791                 :       7493 :     ds_put_char(result, '\n');
    4792                 :       7493 : }
    4793                 :            : 
    4794                 :            : static void trace_report(struct xlate_in *, int indentation,
    4795                 :            :                          const char *format, ...)
    4796                 :            :     OVS_PRINTF_FORMAT(3, 4);
    4797                 :            : static void trace_report_valist(struct xlate_in *, int indentation,
    4798                 :            :                                 const char *format, va_list args)
    4799                 :            :     OVS_PRINTF_FORMAT(3, 0);
    4800                 :            : 
    4801                 :            : static void
    4802                 :       7485 : trace_resubmit(struct xlate_in *xin, struct rule_dpif *rule, int indentation)
    4803                 :            : {
    4804                 :       7485 :     struct trace_ctx *trace = CONTAINER_OF(xin, struct trace_ctx, xin);
    4805                 :       7485 :     struct ds *result = trace->result;
    4806                 :            : 
    4807         [ +  + ]:       7485 :     if (!indentation) {
    4808         [ -  + ]:        873 :         if (rule == xin->ofproto->miss_rule) {
    4809                 :          0 :             trace_report(xin, indentation,
    4810                 :            :                          "No match, flow generates \"packet in\"s.");
    4811         [ +  + ]:        873 :         } else if (rule == xin->ofproto->no_packet_in_rule) {
    4812                 :          5 :             trace_report(xin, indentation, "No match, packets dropped because "
    4813                 :            :                          "OFPPC_NO_PACKET_IN is set on in_port.");
    4814         [ +  + ]:        868 :         } else if (rule == xin->ofproto->drop_frags_rule) {
    4815                 :          2 :             trace_report(xin, indentation,
    4816                 :            :                          "Packets dropped because they are IP fragments and "
    4817                 :            :                          "the fragment handling mode is \"drop\".");
    4818                 :            :         }
    4819                 :            :     }
    4820                 :            : 
    4821                 :       7485 :     ds_put_char(result, '\n');
    4822         [ +  + ]:       7485 :     if (indentation) {
    4823                 :       6612 :         trace_format_flow(result, indentation, "Resubmitted flow", trace);
    4824                 :       6612 :         trace_format_regs(result, indentation, "Resubmitted regs", trace);
    4825                 :       6612 :         trace_format_odp(result,  indentation, "Resubmitted  odp", trace);
    4826                 :       6612 :         trace_format_megaflow(result, indentation, "Resubmitted megaflow",
    4827                 :            :                               trace);
    4828                 :            :     }
    4829                 :       7485 :     trace_format_rule(result, indentation, rule);
    4830                 :       7485 : }
    4831                 :            : 
    4832                 :            : static void
    4833                 :        273 : trace_report_valist(struct xlate_in *xin, int indentation,
    4834                 :            :                     const char *format, va_list args)
    4835                 :            : {
    4836                 :        273 :     struct trace_ctx *trace = CONTAINER_OF(xin, struct trace_ctx, xin);
    4837                 :        273 :     struct ds *result = trace->result;
    4838                 :            : 
    4839                 :        273 :     ds_put_char_multiple(result, '\t', indentation);
    4840                 :        273 :     ds_put_format_valist(result, format, args);
    4841                 :        273 :     ds_put_char(result, '\n');
    4842                 :        273 : }
    4843                 :            : 
    4844                 :            : static void
    4845                 :          7 : trace_report(struct xlate_in *xin, int indentation, const char *format, ...)
    4846                 :            : {
    4847                 :            :     va_list args;
    4848                 :            : 
    4849                 :          7 :     va_start(args, format);
    4850                 :          7 :     trace_report_valist(xin, indentation, format, args);
    4851                 :          7 :     va_end(args);
    4852                 :          7 : }
    4853                 :            : 
    4854                 :            : /* Parses the 'argc' elements of 'argv', ignoring argv[0].  The following
    4855                 :            :  * forms are supported:
    4856                 :            :  *
    4857                 :            :  *     - [dpname] odp_flow [-generate | packet]
    4858                 :            :  *     - bridge br_flow [-generate | packet]
    4859                 :            :  *
    4860                 :            :  * On success, initializes '*ofprotop' and 'flow' and returns NULL.  On failure
    4861                 :            :  * returns a nonnull malloced error message. */
    4862                 :            : static char * OVS_WARN_UNUSED_RESULT
    4863                 :        902 : parse_flow_and_packet(int argc, const char *argv[],
    4864                 :            :                       struct ofproto_dpif **ofprotop, struct flow *flow,
    4865                 :            :                       struct dp_packet **packetp)
    4866                 :            : {
    4867                 :        902 :     const struct dpif_backer *backer = NULL;
    4868                 :        902 :     const char *error = NULL;
    4869                 :        902 :     char *m_err = NULL;
    4870                 :        902 :     struct simap port_names = SIMAP_INITIALIZER(&port_names);
    4871                 :            :     struct dp_packet *packet;
    4872                 :            :     struct ofpbuf odp_key;
    4873                 :            :     struct ofpbuf odp_mask;
    4874                 :            : 
    4875                 :        902 :     ofpbuf_init(&odp_key, 0);
    4876                 :        902 :     ofpbuf_init(&odp_mask, 0);
    4877                 :            : 
    4878                 :            :     /* Handle "-generate" or a hex string as the last argument. */
    4879         [ +  + ]:        902 :     if (!strcmp(argv[argc - 1], "-generate")) {
    4880                 :         96 :         packet = dp_packet_new(0);
    4881                 :         96 :         argc--;
    4882                 :            :     } else {
    4883                 :        806 :         error = eth_from_hex(argv[argc - 1], &packet);
    4884         [ +  + ]:        806 :         if (!error) {
    4885                 :         11 :             argc--;
    4886         [ +  + ]:        795 :         } else if (argc == 4) {
    4887                 :            :             /* The 3-argument form must end in "-generate' or a hex string. */
    4888                 :          1 :             goto exit;
    4889                 :            :         }
    4890                 :        805 :         error = NULL;
    4891                 :            :     }
    4892                 :            : 
    4893                 :            :     /* odp_flow can have its in_port specified as a name instead of port no.
    4894                 :            :      * We do not yet know whether a given flow is a odp_flow or a br_flow.
    4895                 :            :      * But, to know whether a flow is odp_flow through odp_flow_from_string(),
    4896                 :            :      * we need to create a simap of name to port no. */
    4897         [ +  + ]:        901 :     if (argc == 3) {
    4898                 :            :         const char *dp_type;
    4899         [ +  + ]:        891 :         if (!strncmp(argv[1], "ovs-", 4)) {
    4900                 :        319 :             dp_type = argv[1] + 4;
    4901                 :            :         } else {
    4902                 :        572 :             dp_type = argv[1];
    4903                 :            :         }
    4904                 :        891 :         backer = shash_find_data(&all_dpif_backers, dp_type);
    4905         [ +  - ]:         10 :     } else if (argc == 2) {
    4906                 :            :         struct shash_node *node;
    4907         [ +  - ]:         10 :         if (shash_count(&all_dpif_backers) == 1) {
    4908                 :         10 :             node = shash_first(&all_dpif_backers);
    4909                 :         10 :             backer = node->data;
    4910                 :            :         }
    4911                 :            :     } else {
    4912                 :          0 :         error = "Syntax error";
    4913                 :          0 :         goto exit;
    4914                 :            :     }
    4915 [ +  + ][ +  - ]:        901 :     if (backer && backer->dpif) {
    4916                 :            :         struct dpif_port dpif_port;
    4917                 :            :         struct dpif_port_dump port_dump;
    4918 [ +  + ][ +  + ]:       2495 :         DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, backer->dpif) {
    4919                 :       2169 :             simap_put(&port_names, dpif_port.name,
    4920                 :            :                       odp_to_u32(dpif_port.port_no));
    4921                 :            :         }
    4922                 :            :     }
    4923                 :            : 
    4924                 :            :     /* Parse the flow and determine whether a datapath or
    4925                 :            :      * bridge is specified. If function odp_flow_key_from_string()
    4926                 :            :      * returns 0, the flow is a odp_flow. If function
    4927                 :            :      * parse_ofp_exact_flow() returns NULL, the flow is a br_flow. */
    4928         [ +  + ]:        901 :     if (!odp_flow_from_string(argv[argc - 1], &port_names,
    4929                 :            :                               &odp_key, &odp_mask)) {
    4930         [ +  + ]:        332 :         if (!backer) {
    4931                 :         12 :             error = "Cannot find the datapath";
    4932                 :         12 :             goto exit;
    4933                 :            :         }
    4934                 :            : 
    4935         [ -  + ]:        320 :         if (odp_flow_key_to_flow(odp_key.data, odp_key.size, flow) == ODP_FIT_ERROR) {
    4936                 :          0 :             error = "Failed to parse datapath flow key";
    4937                 :          0 :             goto exit;
    4938                 :            :         }
    4939                 :            : 
    4940                 :        320 :         *ofprotop = xlate_lookup_ofproto(backer, flow,
    4941                 :            :                                          &flow->in_port.ofp_port);
    4942         [ +  + ]:        320 :         if (*ofprotop == NULL) {
    4943                 :          2 :             error = "Invalid datapath flow";
    4944                 :          2 :             goto exit;
    4945                 :            :         }
    4946                 :            :     } else {
    4947                 :        569 :         char *err = parse_ofp_exact_flow(flow, NULL, argv[argc - 1], NULL);
    4948                 :            : 
    4949         [ -  + ]:        569 :         if (err) {
    4950                 :          0 :             m_err = xasprintf("Bad openflow flow syntax: %s", err);
    4951                 :          0 :             free(err);
    4952                 :          0 :             goto exit;
    4953                 :            :         } else {
    4954         [ +  + ]:        569 :             if (argc != 3) {
    4955                 :          3 :                 error = "Must specify bridge name";
    4956                 :          3 :                 goto exit;
    4957                 :            :             }
    4958                 :            : 
    4959                 :        566 :             *ofprotop = ofproto_dpif_lookup(argv[1]);
    4960         [ +  + ]:        566 :             if (!*ofprotop) {
    4961                 :          3 :                 error = "Unknown bridge name";
    4962                 :          3 :                 goto exit;
    4963                 :            :             }
    4964                 :            :         }
    4965                 :            :     }
    4966                 :            : 
    4967                 :            :     /* Generate a packet, if requested. */
    4968         [ +  + ]:        881 :     if (packet) {
    4969         [ +  + ]:         95 :         if (!dp_packet_size(packet)) {
    4970                 :         90 :             flow_compose(packet, flow);
    4971                 :            :         } else {
    4972                 :            :             /* Use the metadata from the flow and the packet argument
    4973                 :            :              * to reconstruct the flow. */
    4974                 :          5 :             pkt_metadata_from_flow(&packet->md, flow);
    4975                 :          5 :             flow_extract(packet, flow);
    4976                 :            :         }
    4977                 :            :     }
    4978                 :            : 
    4979                 :            : exit:
    4980 [ +  + ][ +  - ]:        902 :     if (error && !m_err) {
    4981                 :         21 :         m_err = xstrdup(error);
    4982                 :            :     }
    4983         [ +  + ]:        902 :     if (m_err) {
    4984                 :         21 :         dp_packet_delete(packet);
    4985                 :         21 :         packet = NULL;
    4986                 :            :     }
    4987                 :        902 :     *packetp = packet;
    4988                 :        902 :     ofpbuf_uninit(&odp_key);
    4989                 :        902 :     ofpbuf_uninit(&odp_mask);
    4990                 :        902 :     simap_destroy(&port_names);
    4991                 :        902 :     return m_err;
    4992                 :            : }
    4993                 :            : 
    4994                 :            : static void
    4995                 :        901 : ofproto_unixctl_trace(struct unixctl_conn *conn, int argc, const char *argv[],
    4996                 :            :                       void *aux OVS_UNUSED)
    4997                 :            : {
    4998                 :            :     struct ofproto_dpif *ofproto;
    4999                 :            :     struct dp_packet *packet;
    5000                 :            :     char *error;
    5001                 :            :     struct flow flow;
    5002                 :            : 
    5003                 :        901 :     error = parse_flow_and_packet(argc, argv, &ofproto, &flow, &packet);
    5004         [ +  + ]:        901 :     if (!error) {
    5005                 :            :         struct ds result;
    5006                 :            : 
    5007                 :        880 :         ds_init(&result);
    5008                 :        880 :         ofproto_trace(ofproto, &flow, packet, NULL, 0, &result);
    5009                 :        880 :         unixctl_command_reply(conn, ds_cstr(&result));
    5010                 :        880 :         ds_destroy(&result);
    5011                 :        880 :         dp_packet_delete(packet);
    5012                 :            :     } else {
    5013                 :         21 :         unixctl_command_reply_error(conn, error);
    5014                 :         21 :         free(error);
    5015                 :            :     }
    5016                 :        901 : }
    5017                 :            : 
    5018                 :            : static void
    5019                 :          1 : ofproto_unixctl_trace_actions(struct unixctl_conn *conn, int argc,
    5020                 :            :                               const char *argv[], void *aux OVS_UNUSED)
    5021                 :            : {
    5022                 :            :     enum ofputil_protocol usable_protocols;
    5023                 :            :     struct ofproto_dpif *ofproto;
    5024                 :            :     bool enforce_consistency;
    5025                 :            :     struct ofpbuf ofpacts;
    5026                 :            :     struct dp_packet *packet;
    5027                 :            :     struct ds result;
    5028                 :            :     struct flow flow;
    5029                 :            :     uint16_t in_port;
    5030                 :            : 
    5031                 :            :     /* Three kinds of error return values! */
    5032                 :            :     enum ofperr retval;
    5033                 :            :     char *error;
    5034                 :            : 
    5035                 :          1 :     packet = NULL;
    5036                 :          1 :     ds_init(&result);
    5037                 :          1 :     ofpbuf_init(&ofpacts, 0);
    5038                 :            : 
    5039                 :            :     /* Parse actions. */
    5040                 :          1 :     error = ofpacts_parse_actions(argv[--argc], &ofpacts, &usable_protocols);
    5041         [ -  + ]:          1 :     if (error) {
    5042                 :          0 :         unixctl_command_reply_error(conn, error);
    5043                 :          0 :         free(error);
    5044                 :          0 :         goto exit;
    5045                 :            :     }
    5046                 :            : 
    5047                 :            :     /* OpenFlow 1.1 and later suggest that the switch enforces certain forms of
    5048                 :            :      * consistency between the flow and the actions.  With -consistent, we
    5049                 :            :      * enforce consistency even for a flow supported in OpenFlow 1.0. */
    5050         [ -  + ]:          1 :     if (!strcmp(argv[1], "-consistent")) {
    5051                 :          0 :         enforce_consistency = true;
    5052                 :          0 :         argv++;
    5053                 :          0 :         argc--;
    5054                 :            :     } else {
    5055                 :          1 :         enforce_consistency = false;
    5056                 :            :     }
    5057                 :            : 
    5058                 :          1 :     error = parse_flow_and_packet(argc, argv, &ofproto, &flow, &packet);
    5059         [ -  + ]:          1 :     if (error) {
    5060                 :          0 :         unixctl_command_reply_error(conn, error);
    5061                 :          0 :         free(error);
    5062                 :          0 :         goto exit;
    5063                 :            :     }
    5064                 :            : 
    5065                 :            :     /* Do the same checks as handle_packet_out() in ofproto.c.
    5066                 :            :      *
    5067                 :            :      * We pass a 'table_id' of 0 to ofpacts_check(), which isn't
    5068                 :            :      * strictly correct because these actions aren't in any table, but it's OK
    5069                 :            :      * because it 'table_id' is used only to check goto_table instructions, but
    5070                 :            :      * packet-outs take a list of actions and therefore it can't include
    5071                 :            :      * instructions.
    5072                 :            :      *
    5073                 :            :      * We skip the "meter" check here because meter is an instruction, not an
    5074                 :            :      * action, and thus cannot appear in ofpacts. */
    5075                 :          1 :     in_port = ofp_to_u16(flow.in_port.ofp_port);
    5076 [ -  + ][ #  # ]:          1 :     if (in_port >= ofproto->up.max_ports && in_port < ofp_to_u16(OFPP_MAX)) {
    5077                 :          0 :         unixctl_command_reply_error(conn, "invalid in_port");
    5078                 :          0 :         goto exit;
    5079                 :            :     }
    5080         [ -  + ]:          1 :     if (enforce_consistency) {
    5081                 :          0 :         retval = ofpacts_check_consistency(ofpacts.data, ofpacts.size, &flow,
    5082                 :          0 :                                            u16_to_ofp(ofproto->up.max_ports),
    5083                 :          0 :                                            0, ofproto->up.n_tables,
    5084                 :            :                                            usable_protocols);
    5085                 :            :     } else {
    5086                 :          1 :         retval = ofpacts_check(ofpacts.data, ofpacts.size, &flow,
    5087                 :          1 :                                u16_to_ofp(ofproto->up.max_ports), 0,
    5088                 :          1 :                                ofproto->up.n_tables, &usable_protocols);
    5089                 :            :     }
    5090         [ +  - ]:          1 :     if (!retval) {
    5091                 :          1 :         retval = ofproto_check_ofpacts(&ofproto->up, ofpacts.data,
    5092                 :          1 :                                        ofpacts.size);
    5093                 :            :     }
    5094                 :            : 
    5095         [ -  + ]:          1 :     if (retval) {
    5096                 :          0 :         ds_clear(&result);
    5097                 :          0 :         ds_put_format(&result, "Bad actions: %s", ofperr_to_string(retval));
    5098                 :          0 :         unixctl_command_reply_error(conn, ds_cstr(&result));
    5099                 :          0 :         goto exit;
    5100                 :            :     }
    5101                 :            : 
    5102                 :          1 :     ofproto_trace(ofproto, &flow, packet,
    5103                 :          2 :                   ofpacts.data, ofpacts.size, &result);
    5104                 :          1 :     unixctl_command_reply(conn, ds_cstr(&result));
    5105                 :            : 
    5106                 :            : exit:
    5107                 :          1 :     ds_destroy(&result);
    5108                 :          1 :     dp_packet_delete(packet);
    5109                 :          1 :     ofpbuf_uninit(&ofpacts);
    5110                 :          1 : }
    5111                 :            : 
    5112                 :            : /* Implements a "trace" through 'ofproto''s flow table, appending a textual
    5113                 :            :  * description of the results to 'ds'.
    5114                 :            :  *
    5115                 :            :  * The trace follows a packet with the specified 'flow' through the flow
    5116                 :            :  * table.  'packet' may be nonnull to trace an actual packet, with consequent
    5117                 :            :  * side effects (if it is nonnull then its flow must be 'flow').
    5118                 :            :  *
    5119                 :            :  * If 'ofpacts' is nonnull then its 'ofpacts_len' bytes specify the actions to
    5120                 :            :  * trace, otherwise the actions are determined by a flow table lookup. */
    5121                 :            : static void
    5122                 :        881 : ofproto_trace(struct ofproto_dpif *ofproto, struct flow *flow,
    5123                 :            :               const struct dp_packet *packet,
    5124                 :            :               const struct ofpact ofpacts[], size_t ofpacts_len,
    5125                 :            :               struct ds *ds)
    5126                 :            : {
    5127                 :            :     struct trace_ctx trace;
    5128                 :            :     enum xlate_error error;
    5129                 :            : 
    5130                 :        881 :     ds_put_format(ds, "Bridge: %s\n", ofproto->up.name);
    5131                 :        881 :     ds_put_cstr(ds, "Flow: ");
    5132                 :        881 :     flow_format(ds, flow);
    5133                 :        881 :     ds_put_char(ds, '\n');
    5134                 :            : 
    5135                 :        881 :     ofpbuf_init(&trace.odp_actions, 0);
    5136                 :            : 
    5137                 :        881 :     trace.result = ds;
    5138                 :        881 :     trace.key = flow; /* Original flow key, used for megaflow. */
    5139                 :        881 :     trace.flow = *flow; /* May be modified by actions. */
    5140                 :        881 :     xlate_in_init(&trace.xin, ofproto, flow, flow->in_port.ofp_port, NULL,
    5141                 :        881 :                   ntohs(flow->tcp_flags), packet, &trace.wc,
    5142                 :            :                   &trace.odp_actions);
    5143                 :        881 :     trace.xin.ofpacts = ofpacts;
    5144                 :        881 :     trace.xin.ofpacts_len = ofpacts_len;
    5145                 :        881 :     trace.xin.resubmit_hook = trace_resubmit;
    5146                 :        881 :     trace.xin.report_hook = trace_report_valist;
    5147                 :            : 
    5148                 :        881 :     error = xlate_actions(&trace.xin, &trace.xout);
    5149                 :        881 :     ds_put_char(ds, '\n');
    5150                 :        881 :     trace.xin.flow.actset_output = 0;
    5151                 :        881 :     trace_format_flow(ds, 0, "Final flow", &trace);
    5152                 :        881 :     trace_format_megaflow(ds, 0, "Megaflow", &trace);
    5153                 :            : 
    5154                 :        881 :     ds_put_cstr(ds, "Datapath actions: ");
    5155                 :        881 :     format_odp_actions(ds, trace.odp_actions.data, trace.odp_actions.size);
    5156                 :            : 
    5157         [ +  + ]:        881 :     if (error != XLATE_OK) {
    5158                 :          4 :         ds_put_format(ds, "\nTranslation failed (%s), packet is dropped.\n",
    5159                 :            :                       xlate_strerror(error));
    5160         [ +  + ]:        877 :     } else if (trace.xout.slow) {
    5161                 :            :         enum slow_path_reason slow;
    5162                 :            : 
    5163                 :          8 :         ds_put_cstr(ds, "\nThis flow is handled by the userspace "
    5164                 :            :                     "slow path because it:");
    5165                 :            : 
    5166                 :          8 :         slow = trace.xout.slow;
    5167         [ +  + ]:         16 :         while (slow) {
    5168                 :          8 :             enum slow_path_reason bit = rightmost_1bit(slow);
    5169                 :            : 
    5170                 :          8 :             ds_put_format(ds, "\n\t- %s.",
    5171                 :            :                           slow_path_reason_to_explanation(bit));
    5172                 :            : 
    5173                 :          8 :             slow &= ~bit;
    5174                 :            :         }
    5175                 :            :     }
    5176                 :            : 
    5177                 :        881 :     xlate_out_uninit(&trace.xout);
    5178                 :        881 :     ofpbuf_uninit(&trace.odp_actions);
    5179                 :        881 : }
    5180                 :            : 
    5181                 :            : /* Store the current ofprotos in 'ofproto_shash'.  Returns a sorted list
    5182                 :            :  * of the 'ofproto_shash' nodes.  It is the responsibility of the caller
    5183                 :            :  * to destroy 'ofproto_shash' and free the returned value. */
    5184                 :            : static const struct shash_node **
    5185                 :         33 : get_ofprotos(struct shash *ofproto_shash)
    5186                 :            : {
    5187                 :            :     const struct ofproto_dpif *ofproto;
    5188                 :            : 
    5189 [ +  + ][ -  + ]:         74 :     HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
    5190                 :         41 :         char *name = xasprintf("%s@%s", ofproto->up.type, ofproto->up.name);
    5191                 :         41 :         shash_add_nocopy(ofproto_shash, name, ofproto);
    5192                 :            :     }
    5193                 :            : 
    5194                 :         33 :     return shash_sort(ofproto_shash);
    5195                 :            : }
    5196                 :            : 
    5197                 :            : static void
    5198                 :          1 : ofproto_unixctl_dpif_dump_dps(struct unixctl_conn *conn, int argc OVS_UNUSED,
    5199                 :            :                               const char *argv[] OVS_UNUSED,
    5200                 :            :                               void *aux OVS_UNUSED)
    5201                 :            : {
    5202                 :          1 :     struct ds ds = DS_EMPTY_INITIALIZER;
    5203                 :            :     struct shash ofproto_shash;
    5204                 :            :     const struct shash_node **sorted_ofprotos;
    5205                 :            :     int i;
    5206                 :            : 
    5207                 :          1 :     shash_init(&ofproto_shash);
    5208                 :          1 :     sorted_ofprotos = get_ofprotos(&ofproto_shash);
    5209         [ +  + ]:          3 :     for (i = 0; i < shash_count(&ofproto_shash); i++) {
    5210                 :          2 :         const struct shash_node *node = sorted_ofprotos[i];
    5211                 :          2 :         ds_put_format(&ds, "%s\n", node->name);
    5212                 :            :     }
    5213                 :            : 
    5214                 :          1 :     shash_destroy(&ofproto_shash);
    5215                 :          1 :     free(sorted_ofprotos);
    5216                 :            : 
    5217                 :          1 :     unixctl_command_reply(conn, ds_cstr(&ds));
    5218                 :          1 :     ds_destroy(&ds);
    5219                 :          1 : }
    5220                 :            : 
    5221                 :            : static void
    5222                 :         32 : dpif_show_backer(const struct dpif_backer *backer, struct ds *ds)
    5223                 :            : {
    5224                 :            :     const struct shash_node **ofprotos;
    5225                 :            :     struct dpif_dp_stats dp_stats;
    5226                 :            :     struct shash ofproto_shash;
    5227                 :            :     size_t i;
    5228                 :            : 
    5229                 :         32 :     dpif_get_dp_stats(backer->dpif, &dp_stats);
    5230                 :            : 
    5231                 :         32 :     ds_put_format(ds, "%s: hit:%"PRIu64" missed:%"PRIu64"\n",
    5232                 :         32 :                   dpif_name(backer->dpif), dp_stats.n_hit, dp_stats.n_missed);
    5233                 :            : 
    5234                 :         32 :     shash_init(&ofproto_shash);
    5235                 :         32 :     ofprotos = get_ofprotos(&ofproto_shash);
    5236         [ +  + ]:         71 :     for (i = 0; i < shash_count(&ofproto_shash); i++) {
    5237                 :         39 :         struct ofproto_dpif *ofproto = ofprotos[i]->data;
    5238                 :            :         const struct shash_node **ports;
    5239                 :            :         size_t j;
    5240                 :            : 
    5241         [ -  + ]:         39 :         if (ofproto->backer != backer) {
    5242                 :          0 :             continue;
    5243                 :            :         }
    5244                 :            : 
    5245                 :         39 :         ds_put_format(ds, "\t%s:\n", ofproto->up.name);
    5246                 :            : 
    5247                 :         39 :         ports = shash_sort(&ofproto->up.port_by_name);
    5248         [ +  + ]:        150 :         for (j = 0; j < shash_count(&ofproto->up.port_by_name); j++) {
    5249                 :        111 :             const struct shash_node *node = ports[j];
    5250                 :        111 :             struct ofport *ofport = node->data;
    5251                 :            :             struct smap config;
    5252                 :            :             odp_port_t odp_port;
    5253                 :            : 
    5254                 :        111 :             ds_put_format(ds, "\t\t%s %u/", netdev_get_name(ofport->netdev),
    5255                 :            :                           ofport->ofp_port);
    5256                 :            : 
    5257                 :        111 :             odp_port = ofp_port_to_odp_port(ofproto, ofport->ofp_port);
    5258         [ +  + ]:        111 :             if (odp_port != ODPP_NONE) {
    5259                 :        105 :                 ds_put_format(ds, "%"PRIu32":", odp_port);
    5260                 :            :             } else {
    5261                 :          6 :                 ds_put_cstr(ds, "none:");
    5262                 :            :             }
    5263                 :            : 
    5264                 :        111 :             ds_put_format(ds, " (%s", netdev_get_type(ofport->netdev));
    5265                 :            : 
    5266                 :        111 :             smap_init(&config);
    5267         [ +  - ]:        111 :             if (!netdev_get_config(ofport->netdev, &config)) {
    5268                 :            :                 const struct smap_node **nodes;
    5269                 :            :                 size_t i;
    5270                 :            : 
    5271                 :        111 :                 nodes = smap_sort(&config);
    5272         [ +  + ]:        212 :                 for (i = 0; i < smap_count(&config); i++) {
    5273                 :        101 :                     const struct smap_node *node = nodes[i];
    5274         [ +  + ]:        101 :                     ds_put_format(ds, "%c %s=%s", i ? ',' : ':',
    5275                 :            :                                   node->key, node->value);
    5276                 :            :                 }
    5277                 :        111 :                 free(nodes);
    5278                 :            :             }
    5279                 :        111 :             smap_destroy(&config);
    5280                 :            : 
    5281                 :        111 :             ds_put_char(ds, ')');
    5282                 :        111 :             ds_put_char(ds, '\n');
    5283                 :            :         }
    5284                 :         39 :         free(ports);
    5285                 :            :     }
    5286                 :         32 :     shash_destroy(&ofproto_shash);
    5287                 :         32 :     free(ofprotos);
    5288                 :         32 : }
    5289                 :            : 
    5290                 :            : static void
    5291                 :         32 : ofproto_unixctl_dpif_show(struct unixctl_conn *conn, int argc OVS_UNUSED,
    5292                 :            :                           const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED)
    5293                 :            : {
    5294                 :         32 :     struct ds ds = DS_EMPTY_INITIALIZER;
    5295                 :            :     const struct shash_node **backers;
    5296                 :            :     int i;
    5297                 :            : 
    5298                 :         32 :     backers = shash_sort(&all_dpif_backers);
    5299         [ +  + ]:         64 :     for (i = 0; i < shash_count(&all_dpif_backers); i++) {
    5300                 :         32 :         dpif_show_backer(backers[i]->data, &ds);
    5301                 :            :     }
    5302                 :         32 :     free(backers);
    5303                 :            : 
    5304                 :         32 :     unixctl_command_reply(conn, ds_cstr(&ds));
    5305                 :         32 :     ds_destroy(&ds);
    5306                 :         32 : }
    5307                 :            : 
    5308                 :            : static void
    5309                 :         21 : ofproto_unixctl_dpif_dump_flows(struct unixctl_conn *conn,
    5310                 :            :                                 int argc OVS_UNUSED, const char *argv[],
    5311                 :            :                                 void *aux OVS_UNUSED)
    5312                 :            : {
    5313                 :            :     const struct ofproto_dpif *ofproto;
    5314                 :            : 
    5315                 :         21 :     struct ds ds = DS_EMPTY_INITIALIZER;
    5316                 :         21 :     bool verbosity = false;
    5317                 :            : 
    5318                 :            :     struct dpif_port dpif_port;
    5319                 :            :     struct dpif_port_dump port_dump;
    5320                 :            :     struct hmap portno_names;
    5321                 :            : 
    5322                 :            :     struct dpif_flow_dump *flow_dump;
    5323                 :            :     struct dpif_flow_dump_thread *flow_dump_thread;
    5324                 :            :     struct dpif_flow f;
    5325                 :            :     int error;
    5326                 :            : 
    5327                 :         21 :     ofproto = ofproto_dpif_lookup(argv[argc - 1]);
    5328         [ -  + ]:         21 :     if (!ofproto) {
    5329                 :          0 :         unixctl_command_reply_error(conn, "no such bridge");
    5330                 :          0 :         return;
    5331                 :            :     }
    5332                 :            : 
    5333 [ +  + ][ +  - ]:         21 :     if (argc > 2 && !strcmp(argv[1], "-m")) {
    5334                 :          6 :         verbosity = true;
    5335                 :            :     }
    5336                 :            : 
    5337                 :         21 :     hmap_init(&portno_names);
    5338 [ +  + ][ +  + ]:        139 :     DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, ofproto->backer->dpif) {
    5339                 :        118 :         odp_portno_names_set(&portno_names, dpif_port.port_no, dpif_port.name);
    5340                 :            :     }
    5341                 :            : 
    5342                 :         21 :     ds_init(&ds);
    5343                 :         21 :     flow_dump = dpif_flow_dump_create(ofproto->backer->dpif, false);
    5344                 :         21 :     flow_dump_thread = dpif_flow_dump_thread_create(flow_dump);
    5345         [ +  + ]:       2079 :     while (dpif_flow_dump_next(flow_dump_thread, &f, 1)) {
    5346                 :            :         struct flow flow;
    5347                 :            : 
    5348         [ +  - ]:       2058 :         if (odp_flow_key_to_flow(f.key, f.key_len, &flow) == ODP_FIT_ERROR
    5349         [ +  + ]:       2058 :             || xlate_lookup_ofproto(ofproto->backer, &flow, NULL) != ofproto) {
    5350                 :       1085 :             continue;
    5351                 :            :         }
    5352                 :            : 
    5353         [ +  + ]:        973 :         if (verbosity) {
    5354                 :          7 :             odp_format_ufid(&f.ufid, &ds);
    5355                 :          7 :             ds_put_cstr(&ds, " ");
    5356                 :            :         }
    5357                 :        973 :         odp_flow_format(f.key, f.key_len, f.mask, f.mask_len,
    5358                 :            :                         &portno_names, &ds, verbosity);
    5359                 :        973 :         ds_put_cstr(&ds, ", ");
    5360                 :        973 :         dpif_flow_stats_format(&f.stats, &ds);
    5361                 :        973 :         ds_put_cstr(&ds, ", actions:");
    5362                 :        973 :         format_odp_actions(&ds, f.actions, f.actions_len);
    5363                 :        973 :         ds_put_char(&ds, '\n');
    5364                 :            :     }
    5365                 :         21 :     dpif_flow_dump_thread_destroy(flow_dump_thread);
    5366                 :         21 :     error = dpif_flow_dump_destroy(flow_dump);
    5367                 :            : 
    5368         [ -  + ]:         21 :     if (error) {
    5369                 :          0 :         ds_clear(&ds);
    5370                 :          0 :         ds_put_format(&ds, "dpif/dump_flows failed: %s", ovs_strerror(errno));
    5371                 :          0 :         unixctl_command_reply_error(conn, ds_cstr(&ds));
    5372                 :            :     } else {
    5373                 :         21 :         unixctl_command_reply(conn, ds_cstr(&ds));
    5374                 :            :     }
    5375                 :         21 :     odp_portno_names_destroy(&portno_names);
    5376                 :         21 :     hmap_destroy(&portno_names);
    5377                 :         21 :     ds_destroy(&ds);
    5378                 :            : }
    5379                 :            : 
    5380                 :            : static void
    5381                 :         19 : ofproto_revalidate_all_backers(void)
    5382                 :            : {
    5383                 :            :     const struct shash_node **backers;
    5384                 :            :     int i;
    5385                 :            : 
    5386                 :         19 :     backers = shash_sort(&all_dpif_backers);
    5387         [ +  + ]:         38 :     for (i = 0; i < shash_count(&all_dpif_backers); i++) {
    5388                 :         19 :         struct dpif_backer *backer = backers[i]->data;
    5389                 :         19 :         backer->need_revalidate = REV_RECONFIGURE;
    5390                 :            :     }
    5391                 :         19 :     free(backers);
    5392                 :         19 : }
    5393                 :            : 
    5394                 :            : static void
    5395                 :         19 : disable_tnl_push_pop(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED,
    5396                 :            :                      const char *argv[], void *aux OVS_UNUSED)
    5397                 :            : {
    5398         [ +  - ]:         19 :     if (!strcasecmp(argv[1], "off")) {
    5399                 :         19 :         ofproto_use_tnl_push_pop = false;
    5400                 :         19 :         unixctl_command_reply(conn, "Tunnel push-pop off");
    5401                 :         19 :         ofproto_revalidate_all_backers();
    5402         [ #  # ]:          0 :     } else if (!strcasecmp(argv[1], "on")) {
    5403                 :          0 :         ofproto_use_tnl_push_pop = true;
    5404                 :          0 :         unixctl_command_reply(conn, "Tunnel push-pop on");
    5405                 :          0 :         ofproto_revalidate_all_backers();
    5406                 :            :     } else {
    5407                 :          0 :         unixctl_command_reply_error(conn, "Invalid argument");
    5408                 :            :     }
    5409                 :         19 : }
    5410                 :            : 
    5411                 :            : static void
    5412                 :          4 : disable_datapath_truncate(struct unixctl_conn *conn OVS_UNUSED,
    5413                 :            :                           int argc OVS_UNUSED,
    5414                 :            :                           const char *argv[] OVS_UNUSED,
    5415                 :            :                           void *aux OVS_UNUSED)
    5416                 :            : {
    5417                 :            :     const struct shash_node **backers;
    5418                 :            :     int i;
    5419                 :            : 
    5420                 :          4 :     backers = shash_sort(&all_dpif_backers);
    5421         [ +  + ]:          8 :     for (i = 0; i < shash_count(&all_dpif_backers); i++) {
    5422                 :          4 :         struct dpif_backer *backer = backers[i]->data;
    5423                 :          4 :         backer->support.trunc = false;
    5424                 :            :     }
    5425                 :          4 :     free(backers);
    5426                 :          4 :     unixctl_command_reply(conn, "Datapath truncate action diabled");
    5427                 :          4 : }
    5428                 :            : 
    5429                 :            : static void
    5430                 :        615 : ofproto_unixctl_init(void)
    5431                 :            : {
    5432                 :            :     static bool registered;
    5433         [ -  + ]:        615 :     if (registered) {
    5434                 :          0 :         return;
    5435                 :            :     }
    5436                 :        615 :     registered = true;
    5437                 :            : 
    5438                 :        615 :     unixctl_command_register(
    5439                 :            :         "ofproto/trace",
    5440                 :            :         "{[dp_name] odp_flow | bridge br_flow} [-generate|packet]",
    5441                 :            :         1, 3, ofproto_unixctl_trace, NULL);
    5442                 :        615 :     unixctl_command_register(
    5443                 :            :         "ofproto/trace-packet-out",
    5444                 :            :         "[-consistent] {[dp_name] odp_flow | bridge br_flow} [-generate|packet] actions",
    5445                 :            :         2, 6, ofproto_unixctl_trace_actions, NULL);
    5446                 :        615 :     unixctl_command_register("fdb/flush", "[bridge]", 0, 1,
    5447                 :            :                              ofproto_unixctl_fdb_flush, NULL);
    5448                 :        615 :     unixctl_command_register("fdb/show", "bridge", 1, 1,
    5449                 :            :                              ofproto_unixctl_fdb_show, NULL);
    5450                 :        615 :     unixctl_command_register("mdb/flush", "[bridge]", 0, 1,
    5451                 :            :                              ofproto_unixctl_mcast_snooping_flush, NULL);
    5452                 :        615 :     unixctl_command_register("mdb/show", "bridge", 1, 1,
    5453                 :            :                              ofproto_unixctl_mcast_snooping_show, NULL);
    5454                 :        615 :     unixctl_command_register("dpif/dump-dps", "", 0, 0,
    5455                 :            :                              ofproto_unixctl_dpif_dump_dps, NULL);
    5456                 :        615 :     unixctl_command_register("dpif/show", "", 0, 0, ofproto_unixctl_dpif_show,
    5457                 :            :                              NULL);
    5458                 :        615 :     unixctl_command_register("dpif/dump-flows", "[-m] bridge", 1, 2,
    5459                 :            :                              ofproto_unixctl_dpif_dump_flows, NULL);
    5460                 :            : 
    5461                 :        615 :     unixctl_command_register("ofproto/tnl-push-pop", "[on]|[off]", 1, 1,
    5462                 :            :                              disable_tnl_push_pop, NULL);
    5463                 :            : 
    5464                 :        615 :     unixctl_command_register("dpif/disable-truncate", "", 0, 0,
    5465                 :            :                              disable_datapath_truncate, NULL);
    5466                 :            : }
    5467                 :            : 
    5468                 :            : /* Returns true if 'table' is the table used for internal rules,
    5469                 :            :  * false otherwise. */
    5470                 :            : bool
    5471                 :          0 : table_is_internal(uint8_t table_id)
    5472                 :            : {
    5473                 :          0 :     return table_id == TBL_INTERNAL;
    5474                 :            : }
    5475                 :            : 
    5476                 :            : 
    5477                 :            : static odp_port_t
    5478                 :       8371 : ofp_port_to_odp_port(const struct ofproto_dpif *ofproto, ofp_port_t ofp_port)
    5479                 :            : {
    5480                 :       8371 :     const struct ofport_dpif *ofport = ofp_port_to_ofport(ofproto, ofp_port);
    5481         [ +  + ]:       8371 :     return ofport ? ofport->odp_port : ODPP_NONE;
    5482                 :            : }
    5483                 :            : 
    5484                 :            : struct ofport_dpif *
    5485                 :      88064 : odp_port_to_ofport(const struct dpif_backer *backer, odp_port_t odp_port)
    5486                 :            : {
    5487                 :            :     struct ofport_dpif *port;
    5488                 :            : 
    5489                 :      88064 :     ovs_rwlock_rdlock(&backer->odp_to_ofport_lock);
    5490 [ +  + ][ -  + ]:     127150 :     HMAP_FOR_EACH_IN_BUCKET (port, odp_port_node, hash_odp_port(odp_port),
    5491                 :            :                              &backer->odp_to_ofport_map) {
    5492         [ +  + ]:     122378 :         if (port->odp_port == odp_port) {
    5493                 :      83292 :             ovs_rwlock_unlock(&backer->odp_to_ofport_lock);
    5494                 :      83292 :             return port;
    5495                 :            :         }
    5496                 :            :     }
    5497                 :            : 
    5498                 :       4772 :     ovs_rwlock_unlock(&backer->odp_to_ofport_lock);
    5499                 :       4772 :     return NULL;
    5500                 :            : }
    5501                 :            : 
    5502                 :            : static ofp_port_t
    5503                 :      18683 : odp_port_to_ofp_port(const struct ofproto_dpif *ofproto, odp_port_t odp_port)
    5504                 :            : {
    5505                 :            :     struct ofport_dpif *port;
    5506                 :            : 
    5507                 :      18683 :     port = odp_port_to_ofport(ofproto->backer, odp_port);
    5508 [ +  + ][ +  - ]:      18683 :     if (port && &ofproto->up == port->up.ofproto) {
    5509                 :      14588 :         return port->up.ofp_port;
    5510                 :            :     } else {
    5511                 :       4095 :         return OFPP_NONE;
    5512                 :            :     }
    5513                 :            : }
    5514                 :            : 
    5515                 :            : int
    5516                 :       4788 : ofproto_dpif_add_internal_flow(struct ofproto_dpif *ofproto,
    5517                 :            :                                const struct match *match, int priority,
    5518                 :            :                                uint16_t idle_timeout,
    5519                 :            :                                const struct ofpbuf *ofpacts,
    5520                 :            :                                struct rule **rulep)
    5521                 :            : {
    5522                 :            :     struct ofputil_flow_mod fm;
    5523                 :            :     struct rule_dpif *rule;
    5524                 :            :     int error;
    5525                 :            : 
    5526                 :       4788 :     fm = (struct ofputil_flow_mod) {
    5527                 :            :         .buffer_id = UINT32_MAX,
    5528                 :       4788 :         .match = *match,
    5529                 :            :         .priority = priority,
    5530                 :            :         .table_id = TBL_INTERNAL,
    5531                 :            :         .command = OFPFC_ADD,
    5532                 :            :         .idle_timeout = idle_timeout,
    5533                 :            :         .flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY,
    5534                 :       4788 :         .ofpacts = ofpacts->data,
    5535                 :       4788 :         .ofpacts_len = ofpacts->size,
    5536                 :            :     };
    5537                 :            : 
    5538                 :       4788 :     error = ofproto_flow_mod(&ofproto->up, &fm);
    5539         [ -  + ]:       4788 :     if (error) {
    5540         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "failed to add internal flow (%s)",
    5541                 :            :                     ofperr_to_string(error));
    5542                 :          0 :         *rulep = NULL;
    5543                 :          0 :         return error;
    5544                 :            :     }
    5545                 :            : 
    5546                 :       4788 :     rule = rule_dpif_lookup_in_table(ofproto,
    5547                 :            :                                      ofproto_dpif_get_tables_version(ofproto),
    5548                 :            :                                      TBL_INTERNAL, &fm.match.flow,
    5549                 :            :                                      &fm.match.wc);
    5550         [ +  - ]:       4788 :     if (rule) {
    5551                 :       4788 :         *rulep = &rule->up;
    5552                 :            :     } else {
    5553                 :          0 :         OVS_NOT_REACHED();
    5554                 :            :     }
    5555                 :       4788 :     return 0;
    5556                 :            : }
    5557                 :            : 
    5558                 :            : int
    5559                 :        512 : ofproto_dpif_delete_internal_flow(struct ofproto_dpif *ofproto,
    5560                 :            :                                   struct match *match, int priority)
    5561                 :            : {
    5562                 :            :     struct ofputil_flow_mod fm;
    5563                 :            :     int error;
    5564                 :            : 
    5565                 :        512 :     fm = (struct ofputil_flow_mod) {
    5566                 :            :         .buffer_id = UINT32_MAX,
    5567                 :        512 :         .match = *match,
    5568                 :            :         .priority = priority,
    5569                 :            :         .table_id = TBL_INTERNAL,
    5570                 :            :         .flags = OFPUTIL_FF_HIDDEN_FIELDS | OFPUTIL_FF_NO_READONLY,
    5571                 :            :         .command = OFPFC_DELETE_STRICT,
    5572                 :            :     };
    5573                 :            : 
    5574                 :        512 :     error = ofproto_flow_mod(&ofproto->up, &fm);
    5575         [ -  + ]:        512 :     if (error) {
    5576         [ #  # ]:          0 :         VLOG_ERR_RL(&rl, "failed to delete internal flow (%s)",
    5577                 :            :                     ofperr_to_string(error));
    5578                 :          0 :         return error;
    5579                 :            :     }
    5580                 :            : 
    5581                 :        512 :     return 0;
    5582                 :            : }
    5583                 :            : 
    5584                 :            : const struct uuid *
    5585                 :       3711 : ofproto_dpif_get_uuid(const struct ofproto_dpif *ofproto)
    5586                 :            : {
    5587                 :       3711 :     return &ofproto->uuid;
    5588                 :            : }
    5589                 :            : 
    5590                 :            : const struct ofproto_class ofproto_dpif_class = {
    5591                 :            :     init,
    5592                 :            :     enumerate_types,
    5593                 :            :     enumerate_names,
    5594                 :            :     del,
    5595                 :            :     port_open_type,
    5596                 :            :     type_run,
    5597                 :            :     type_wait,
    5598                 :            :     alloc,
    5599                 :            :     construct,
    5600                 :            :     destruct,
    5601                 :            :     dealloc,
    5602                 :            :     run,
    5603                 :            :     ofproto_dpif_wait,
    5604                 :            :     NULL,                       /* get_memory_usage. */
    5605                 :            :     type_get_memory_usage,
    5606                 :            :     flush,
    5607                 :            :     query_tables,
    5608                 :            :     set_tables_version,
    5609                 :            :     port_alloc,
    5610                 :            :     port_construct,
    5611                 :            :     port_destruct,
    5612                 :            :     port_dealloc,
    5613                 :            :     port_modified,
    5614                 :            :     port_reconfigured,
    5615                 :            :     port_query_by_name,
    5616                 :            :     port_add,
    5617                 :            :     port_del,
    5618                 :            :     port_set_config,
    5619                 :            :     port_get_stats,
    5620                 :            :     port_dump_start,
    5621                 :            :     port_dump_next,
    5622                 :            :     port_dump_done,
    5623                 :            :     port_poll,
    5624                 :            :     port_poll_wait,
    5625                 :            :     port_is_lacp_current,
    5626                 :            :     port_get_lacp_stats,
    5627                 :            :     NULL,                       /* rule_choose_table */
    5628                 :            :     rule_alloc,
    5629                 :            :     rule_construct,
    5630                 :            :     rule_insert,
    5631                 :            :     NULL,                       /* rule_delete */
    5632                 :            :     rule_destruct,
    5633                 :            :     rule_dealloc,
    5634                 :            :     rule_get_stats,
    5635                 :            :     set_frag_handling,
    5636                 :            :     packet_out,
    5637                 :            :     nxt_resume,
    5638                 :            :     set_netflow,
    5639                 :            :     get_netflow_ids,
    5640                 :            :     set_sflow,
    5641                 :            :     set_ipfix,
    5642                 :            :     get_ipfix_stats,
    5643                 :            :     set_cfm,
    5644                 :            :     cfm_status_changed,
    5645                 :            :     get_cfm_status,
    5646                 :            :     set_lldp,
    5647                 :            :     get_lldp_status,
    5648                 :            :     set_aa,
    5649                 :            :     aa_mapping_set,
    5650                 :            :     aa_mapping_unset,
    5651                 :            :     aa_vlan_get_queued,
    5652                 :            :     aa_vlan_get_queue_size,
    5653                 :            :     set_bfd,
    5654                 :            :     bfd_status_changed,
    5655                 :            :     get_bfd_status,
    5656                 :            :     set_stp,
    5657                 :            :     get_stp_status,
    5658                 :            :     set_stp_port,
    5659                 :            :     get_stp_port_status,
    5660                 :            :     get_stp_port_stats,
    5661                 :            :     set_rstp,
    5662                 :            :     get_rstp_status,
    5663                 :            :     set_rstp_port,
    5664                 :            :     get_rstp_port_status,
    5665                 :            :     set_queues,
    5666                 :            :     bundle_set,
    5667                 :            :     bundle_remove,
    5668                 :            :     mirror_set__,
    5669                 :            :     mirror_get_stats__,
    5670                 :            :     set_flood_vlans,
    5671                 :            :     is_mirror_output_bundle,
    5672                 :            :     forward_bpdu_changed,
    5673                 :            :     set_mac_table_config,
    5674                 :            :     set_mcast_snooping,
    5675                 :            :     set_mcast_snooping_port,
    5676                 :            :     NULL,                       /* meter_get_features */
    5677                 :            :     NULL,                       /* meter_set */
    5678                 :            :     NULL,                       /* meter_get */
    5679                 :            :     NULL,                       /* meter_del */
    5680                 :            :     group_alloc,                /* group_alloc */
    5681                 :            :     group_construct,            /* group_construct */
    5682                 :            :     group_destruct,             /* group_destruct */
    5683                 :            :     group_dealloc,              /* group_dealloc */
    5684                 :            :     group_modify,               /* group_modify */
    5685                 :            :     group_get_stats,            /* group_get_stats */
    5686                 :            :     get_datapath_version,       /* get_datapath_version */
    5687                 :            : };

Generated by: LCOV version 1.12