@@ -214,22 +214,34 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
ofp_port_t ofport;
struct ovs_list bindings;
};
- /* A list of localnet port bindings hashed by network name */
+ /* Maps from network name to "struct localnet_bindings". */
struct shash localnet_inputs = SHASH_INITIALIZER(&localnet_inputs);
- /* Datapaths with at least one local port binding */
+ /* Contains bare "struct hmap_node"s whose hash values are the tunnel_key
+ * of datapaths with at least one local port binding. */
struct hmap local_datapaths = HMAP_INITIALIZER(&local_datapaths);
/* Set up flows in table 0 for physical-to-logical translation and in table
* 64 for logical-to-physical translation. */
const struct sbrec_port_binding *binding;
SBREC_PORT_BINDING_FOR_EACH (binding, ctx->ovnsb_idl) {
- /* Find the OpenFlow port for the logical port, as 'ofport'. If it's
- * on a remote chassis, this is the OpenFlow port for the tunnel to
- * that chassis (and set 'local' to false). Otherwise, if it's on the
- * chassis we're managing, this is the OpenFlow port for the vif itself
- * (and set 'local' to true). When 'parent_port' is set for a binding,
- * it implies a container sitting inside a VM reachable via a 'tag'.
+ /* Find the OpenFlow port for the logical port, as 'ofport'. This is
+ * one of:
+ *
+ * - If the port is a VIF on the chassis we're managing, the
+ * OpenFlow port for the VIF. 'tun' will be NULL.
+ *
+ * In this or the next case, for a container nested inside a VM
+ * and accessible via a VLAN, 'tag' is the VLAN ID; otherwise
+ * 'tag' is 0.
+ *
+ * - If the port is on a remote chassis, the OpenFlow port for a
+ * tunnel to the VIF's remote chassis. 'tun' identifies that
+ * tunnel.
+ *
+ * - If the port is a "localnet" port for a network that is
+ * attached to the chassis we're managing, the OpenFlow port for
+ * the localnet port (a patch port).
*/
int tag = 0;
@@ -287,18 +299,17 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
* attached to more than one logical datapath, so keep track of
* all associated bindings and add a flow at the end. */
- const char *network = smap_get(&binding->options, "network_name");
- struct shash_node *node;
+ const char *network
+ = smap_get(&binding->options, "network_name");
struct localnet_bindings *ln_bindings;
- node = shash_find(&localnet_inputs, network);
- if (!node) {
+ ln_bindings = shash_find_data(&localnet_inputs, network);
+ if (!ln_bindings) {
ln_bindings = xmalloc(sizeof *ln_bindings);
ln_bindings->ofport = ofport;
list_init(&ln_bindings->bindings);
- node = shash_add(&localnet_inputs, network, ln_bindings);
+ shash_add(&localnet_inputs, network, ln_bindings);
}
- ln_bindings = node->data;
struct binding_elem *b = xmalloc(sizeof *b);
b->binding = binding;
@@ -594,14 +605,14 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
/* Table 0, Priority 100
* =====================
*
- * We have now determined the full set of port bindings associated with each
- * "localnet" network. Only create flows for datapaths that have another
- * local binding. Otherwise, we know it would just be dropped.
+ * We have now determined the full set of port bindings associated with
+ * each "localnet" network. Only create flows for datapaths that have
+ * another local binding. Otherwise, we know it would just be dropped.
*/
struct shash_node *ln_bindings_node, *ln_bindings_node_next;
- struct localnet_bindings *ln_bindings;
- SHASH_FOR_EACH_SAFE (ln_bindings_node, ln_bindings_node_next, &localnet_inputs) {
- ln_bindings = ln_bindings_node->data;
+ SHASH_FOR_EACH_SAFE (ln_bindings_node, ln_bindings_node_next,
+ &localnet_inputs) {
+ struct localnet_bindings *ln_bindings = ln_bindings_node->data;
struct match match;
match_init_catchall(&match);
@@ -610,16 +621,12 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
struct ofpbuf ofpacts;
ofpbuf_init(&ofpacts, 0);
- bool found_local = false;
struct binding_elem *b;
LIST_FOR_EACH_POP (b, list_elem, &ln_bindings->bindings) {
struct hmap_node *ld;
ld = hmap_first_with_hash(&local_datapaths,
b->binding->datapath->tunnel_key);
if (ld) {
- /* This datapath has local port bindings. */
- found_local = true;
-
/* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
put_load(b->binding->datapath->tunnel_key, MFF_LOG_DATAPATH,
0, 64, &ofpacts);
@@ -631,7 +638,7 @@ physical_run(struct controller_ctx *ctx, enum mf_field_id mff_ovn_geneve,
free(b);
}
- if (found_local) {
+ if (ofpacts.size) {
ofctrl_add_flow(flow_table, 0, 100, &match, &ofpacts);
}
@@ -116,24 +116,26 @@
</p>
<p>
- When this column is set to <em>localnet</em>, this logical port represents a
- connection to a locally accessible network from each ovn-controller instance.
- A logical switch can only have a single <em>localnet</em> port attached
- and at most one regular logical port. This is used to model direct
- connectivity to an existing network.
+ When this column is set to <code>localnet</code>, this logical port
+ represents a connection to a locally accessible network from each
+ <code>ovn-controller</code> instance. A logical switch can only have a
+ single <code>localnet</code> port attached and at most one regular
+ logical port. This is used to model direct connectivity to an existing
+ network.
</p>
</column>
<column name="options">
<p>
- This column provides key/value settings specific to the logical port
- <ref column="type"/>.
+ This column provides key/value settings specific to the logical port
+ <ref column="type"/>.
</p>
<p>
- When <ref column="type"/> is set to <em>localnet</em>, you must set the option
- <em>network_name</em>. ovn-controller uses local configuration to determine
- exactly how to connect to this locally accessible network.
+ When <ref column="type"/> is set to <code>localnet</code>, you must set
+ the option <code>network_name</code>. <code>ovn-controller</code> uses
+ local configuration to determine exactly how to connect to this locally
+ accessible network.
</p>
</column>
@@ -964,39 +964,42 @@
</p>
<p>
- When this column is set to <em>localnet</em>, this logical port represents a
- connection to a locally accessible network from each ovn-controller instance.
- A logical switch can only have a single <em>localnet</em> port attached
- and at most one regular logical port. This is used to model direct
- connectivity to an existing network.
+ When this column is set to <code>localnet</code>, this logical port
+ represents a connection to a locally accessible network from each
+ ovn-controller instance. A logical switch can only have a single
+ <code>localnet</code> port attached and at most one regular logical
+ port. This is used to model direct connectivity to an existing
+ network.
</p>
</column>
<column name="options">
<p>
- This column provides key/value settings specific to the logical port
- <ref column="type"/>.
+ This column provides key/value settings specific to the logical port
+ <ref column="type"/>.
</p>
<p>
- When <ref column="type"/> is set to <em>localnet</em>, you must set the option
- <em>network_name</em>. ovn-controller uses the configuration entry
- <em>ovn-bridge-mappings</em> to determine how to connect to this network.
- <em>ovn-bridge-mappings</em> is a list of network names mapped to a local
- OVS bridge that provides access to that network. An example of configuring
- <em>ovn-bridge-mappings</em> would be:
+ When <ref column="type"/> is set to <code>localnet</code>, you must set
+ the option <code>network_name</code>. <code>ovn-controller</code> uses
+ the configuration entry <code>ovn-bridge-mappings</code> to determine
+ how to connect to this network. <code>ovn-bridge-mappings</code> is a
+ list of network names mapped to a local OVS bridge that provides access
+ to that network. An example of configuring
+ <code>ovn-bridge-mappings</code> would be:
</p>
<p>
- <em>$ ovs-vsctl set open . external-ids:ovn-bridge-mappings=physnet1:br-eth0,physnet2:br-eth1</em>
+ <code>$ ovs-vsctl set open
+ . external-ids:ovn-bridge-mappings=physnet1:br-eth0,physnet2:br-eth1</code>
</p>
<p>
- Also note that when a logical switch has a <em>localnet</em> port attached,
- every chassis that may have a local vif attached to that logical switch
- must have a bridge mapping configured to reach that <em>localnet</em>.
- Traffic that arrives on a <em>localnet</em> port is never forwarded over a tunnel
- to another chassis.
+ Also note that when a logical switch has a <code>localnet</code> port
+ attached, every chassis that may have a local vif attached to that
+ logical switch must have a bridge mapping configured to reach that
+ <code>localnet</code>. Traffic that arrives on a <code>localnet</code>
+ port is never forwarded over a tunnel to another chassis.
</p>
</column>