build_lflows(struct northd_context *ctx, struct hmap *datapaths,
struct hmap *ports)
{
+ /* This flow table structure is documented in ovn-northd(8), so please
+ * update ovn-northd.8.xml if you change anything. */
+
struct hmap lflows = HMAP_INITIALIZER(&lflows);
struct hmap mcgroups = HMAP_INITIALIZER(&mcgroups);
/* Port security flows have priority 50 (see below) and will continue
* to the next table if packet source is acceptable. */
-
- /* Otherwise drop the packet. */
- ovn_lflow_add(&lflows, od, P_IN, S_IN_PORT_SEC, 0, "1", "drop;");
}
/* Ingress table 0: Ingress port security (priority 50). */
struct ovn_port *op;
HMAP_FOR_EACH (op, key_node, ports) {
+ if (!lport_is_enabled(op->nb)) {
+ /* Drop packets from disabled logical ports (since logical flow
+ * tables are default-drop). */
+ continue;
+ }
+
struct ds match = DS_EMPTY_INITIALIZER;
ds_put_cstr(&match, "inport == ");
json_string_escape(op->key, &match);
build_port_security("eth.src",
op->nb->port_security, op->nb->n_port_security,
&match);
- ovn_lflow_add(&lflows, op->od, P_IN, S_IN_PORT_SEC, 50, ds_cstr(&match),
- lport_is_enabled(op->nb) ? "next;" : "drop;");
+ ovn_lflow_add(&lflows, op->od, P_IN, S_IN_PORT_SEC, 50,
+ ds_cstr(&match), "next;");
ds_destroy(&match);
}
ds_destroy(&actions);
ds_destroy(&match);
} else if (!strcmp(op->nb->macs[i], "unknown")) {
- ovn_multicast_add(&mcgroups, &mc_unknown, op);
- op->od->has_unknown = true;
+ if (lport_is_enabled(op->nb)) {
+ ovn_multicast_add(&mcgroups, &mc_unknown, op);
+ op->od->has_unknown = true;
+ }
} else {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
"output;");
}
- /* Egress table 1: Egress port security (priority 50). */
+ /* Egress table 1: Egress port security (priorities 50 and 150).
+ *
+ * Priority 50 rules implement port security for enabled logical port.
+ *
+ * Priority 150 rules drop packets to disabled logical ports, so that they
+ * don't even receive multicast or broadcast packets. */
HMAP_FOR_EACH (op, key_node, ports) {
struct ds match;
ds_init(&match);
ds_put_cstr(&match, "outport == ");
json_string_escape(op->key, &match);
- build_port_security("eth.dst",
- op->nb->port_security, op->nb->n_port_security,
- &match);
-
- ovn_lflow_add(&lflows, op->od, P_OUT, S_OUT_PORT_SEC, 50,
- ds_cstr(&match),
- lport_is_enabled(op->nb) ? "output;" : "drop;");
+ if (lport_is_enabled(op->nb)) {
+ build_port_security("eth.dst",
+ op->nb->port_security, op->nb->n_port_security,
+ &match);
+ ovn_lflow_add(&lflows, op->od, P_OUT, S_OUT_PORT_SEC, 50,
+ ds_cstr(&match), "output;");
+ } else {
+ ovn_lflow_add(&lflows, op->od, P_OUT, S_OUT_PORT_SEC, 150,
+ ds_cstr(&match), "drop;");
+ }
ds_destroy(&match);
}
vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
parse_options(argc, argv);
- daemonize_start();
+ daemonize_start(false);
retval = unixctl_server_create(NULL, &unixctl);
if (retval) {