Skip to content

Commit

Permalink
Add new egress tables to accommodate for too-big packets handling
Browse files Browse the repository at this point in the history
The new tables will be used in a later patch as follows:

table=37, OFTABLE_OUTPUT_INIT: becomes an initial entry point into the
egress pipeline that serves a semantic goal. (Not doing any actual
processing at the moment.)

table=38, OFTABLE_OUTPUT_LARGE_PKT_DETECT: detect "too-big" IP packets
and mark them for later processing in table=39.

table=39, OFTABLE_OUTPUT_LARGE_PKT_PROCESS: process "too-big" IP packets
detected in table=38 by sending ICMPv4 Fragmentation Needed / ICMPv6 Too
Big errors back to the originating port.

All previous table indices shifted by 3 (old table=37 becomes table=40).
Otherwise, no changes to existing tables and flows introduced.

Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ihar Hrachyshka <ihrachys@redhat.com>
Signed-off-by: Mark Michelson <mmichels@redhat.com>
  • Loading branch information
booxter authored and putnopvut committed May 30, 2023
1 parent 842138e commit 740f23c
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 384 deletions.
4 changes: 2 additions & 2 deletions controller/lflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ consider_lflow_for_added_as_ips__(
: OFTABLE_LOG_EGRESS_PIPELINE);
uint8_t ptable = first_ptable + lflow->table_id;
uint8_t output_ptable = (ingress
? OFTABLE_REMOTE_OUTPUT
? OFTABLE_OUTPUT_INIT
: OFTABLE_SAVE_INPORT);

uint64_t ovnacts_stub[1024 / 8];
Expand Down Expand Up @@ -1067,7 +1067,7 @@ consider_logical_flow__(const struct sbrec_logical_flow *lflow,
: OFTABLE_LOG_EGRESS_PIPELINE);
uint8_t ptable = first_ptable + lflow->table_id;
uint8_t output_ptable = (ingress
? OFTABLE_REMOTE_OUTPUT
? OFTABLE_OUTPUT_INIT
: OFTABLE_SAVE_INPORT);

/* Parse OVN logical actions.
Expand Down
49 changes: 28 additions & 21 deletions controller/lflow.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,27 +63,34 @@ struct uuid;
*
* These are heavily documented in ovn-architecture(7), please update it if
* you make any changes. */
#define OFTABLE_PHY_TO_LOG 0
#define OFTABLE_LOG_INGRESS_PIPELINE 8 /* First of LOG_PIPELINE_LEN tables. */
#define OFTABLE_REMOTE_OUTPUT 37
#define OFTABLE_LOCAL_OUTPUT 38
#define OFTABLE_CHECK_LOOPBACK 39
#define OFTABLE_LOG_EGRESS_PIPELINE 40 /* First of LOG_PIPELINE_LEN tables. */
#define OFTABLE_SAVE_INPORT 64
#define OFTABLE_LOG_TO_PHY 65
#define OFTABLE_MAC_BINDING 66
#define OFTABLE_MAC_LOOKUP 67
#define OFTABLE_CHK_LB_HAIRPIN 68
#define OFTABLE_CHK_LB_HAIRPIN_REPLY 69
#define OFTABLE_CT_SNAT_HAIRPIN 70
#define OFTABLE_GET_FDB 71
#define OFTABLE_LOOKUP_FDB 72
#define OFTABLE_CHK_IN_PORT_SEC 73
#define OFTABLE_CHK_IN_PORT_SEC_ND 74
#define OFTABLE_CHK_OUT_PORT_SEC 75
#define OFTABLE_ECMP_NH_MAC 76
#define OFTABLE_ECMP_NH 77
#define OFTABLE_CHK_LB_AFFINITY 78
#define OFTABLE_PHY_TO_LOG 0

/* Start of LOG_PIPELINE_LEN tables. */
#define OFTABLE_LOG_INGRESS_PIPELINE 8
#define OFTABLE_OUTPUT_INIT 37
#define OFTABLE_OUTPUT_LARGE_PKT_DETECT 38
#define OFTABLE_OUTPUT_LARGE_PKT_PROCESS 39
#define OFTABLE_REMOTE_OUTPUT 40
#define OFTABLE_LOCAL_OUTPUT 41
#define OFTABLE_CHECK_LOOPBACK 42

/* Start of LOG_PIPELINE_LEN tables. */
#define OFTABLE_LOG_EGRESS_PIPELINE 43
#define OFTABLE_SAVE_INPORT 64
#define OFTABLE_LOG_TO_PHY 65
#define OFTABLE_MAC_BINDING 66
#define OFTABLE_MAC_LOOKUP 67
#define OFTABLE_CHK_LB_HAIRPIN 68
#define OFTABLE_CHK_LB_HAIRPIN_REPLY 69
#define OFTABLE_CT_SNAT_HAIRPIN 70
#define OFTABLE_GET_FDB 71
#define OFTABLE_LOOKUP_FDB 72
#define OFTABLE_CHK_IN_PORT_SEC 73
#define OFTABLE_CHK_IN_PORT_SEC_ND 74
#define OFTABLE_CHK_OUT_PORT_SEC 75
#define OFTABLE_ECMP_NH_MAC 76
#define OFTABLE_ECMP_NH 77
#define OFTABLE_CHK_LB_AFFINITY 78

struct lflow_ctx_in {
struct ovsdb_idl_index *sbrec_multicast_group_by_name_datapath;
Expand Down
77 changes: 50 additions & 27 deletions controller/physical.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,12 +876,12 @@ put_local_common_flows(uint32_t dp_key,

uint32_t port_key = pb->tunnel_key;

/* Table 38, priority 100.
/* Table 41, priority 100.
* =======================
*
* Implements output to local hypervisor. Each flow matches a
* logical output port on the local hypervisor, and resubmits to
* table 39.
* table 42.
*/

ofpbuf_clear(ofpacts_p);
Expand All @@ -891,13 +891,13 @@ put_local_common_flows(uint32_t dp_key,

put_zones_ofpacts(zone_ids, ofpacts_p);

/* Resubmit to table 39. */
/* Resubmit to table 42. */
put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p);
ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100,
pb->header_.uuid.parts[0], &match, ofpacts_p,
&pb->header_.uuid);

/* Table 39, Priority 100.
/* Table 42, Priority 100.
* =======================
*
* Drop packets whose logical inport and outport are the same
Expand Down Expand Up @@ -1233,12 +1233,12 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
|| ha_chassis_group_is_active(binding->ha_chassis_group,
active_tunnels, chassis))) {

/* Table 38, priority 100.
/* Table 41, priority 100.
* =======================
*
* Implements output to local hypervisor. Each flow matches a
* logical output port on the local hypervisor, and resubmits to
* table 39. For ports of type "chassisredirect", the logical
* table 42. For ports of type "chassisredirect", the logical
* output port is changed from the "chassisredirect" port to the
* underlying distributed port. */

Expand Down Expand Up @@ -1275,7 +1275,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
ct_zones);
put_zones_ofpacts(&zone_ids, ofpacts_p);

/* Resubmit to table 39. */
/* Resubmit to table 42. */
put_resubmit(OFTABLE_CHECK_LOOPBACK, ofpacts_p);
}

Expand Down Expand Up @@ -1491,7 +1491,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
ofport, flow_table);
}

/* Table 39, priority 160.
/* Table 42, priority 160.
* =======================
*
* Do not forward local traffic from a localport to a localnet port.
Expand Down Expand Up @@ -1561,13 +1561,13 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
}
}

/* Table 37, priority 150.
/* Table 40, priority 150.
* =======================
*
* Handles packets received from ports of type "localport". These
* ports are present on every hypervisor. Traffic that originates at
* one should never go over a tunnel to a remote hypervisor,
* so resubmit them to table 38 for local delivery. */
* so resubmit them to table 41 for local delivery. */
if (!strcmp(binding->type, "localport")) {
ofpbuf_clear(ofpacts_p);
put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p);
Expand All @@ -1581,7 +1581,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
}
} else if (access_type == PORT_LOCALNET) {
/* Remote port connected by localnet port */
/* Table 38, priority 100.
/* Table 41, priority 100.
* =======================
*
* Implements switching to localnet port. Each flow matches a
Expand All @@ -1596,7 +1596,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,

put_load(localnet_port->tunnel_key, MFF_LOG_OUTPORT, 0, 32, ofpacts_p);

/* Resubmit to table 38. */
/* Resubmit to table 41. */
put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p);
ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 100,
binding->header_.uuid.parts[0],
Expand All @@ -1613,7 +1613,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
const char *redirect_type = smap_get(&binding->options,
"redirect-type");

/* Table 38, priority 100.
/* Table 41, priority 100.
* =======================
*
* Handles traffic that needs to be sent to a remote hypervisor. Each
Expand Down Expand Up @@ -1838,7 +1838,7 @@ consider_mc_group(struct ovsdb_idl_index *sbrec_port_binding_by_name,
}
}

/* Table 38, priority 100.
/* Table 41, priority 100.
* =======================
*
* Handle output to the local logical ports in the multicast group, if
Expand All @@ -1854,7 +1854,7 @@ consider_mc_group(struct ovsdb_idl_index *sbrec_port_binding_by_name,
&match, &ofpacts, &mc->header_.uuid);
}

/* Table 37, priority 100.
/* Table 40, priority 100.
* =======================
*
* Handle output to the remote chassis in the multicast group, if
Expand Down Expand Up @@ -2032,7 +2032,7 @@ physical_run(struct physical_ctx *p_ctx,
flow_table, &ofpacts);
}

/* Handle output to multicast groups, in tables 37 and 38. */
/* Handle output to multicast groups, in tables 40 and 41. */
const struct sbrec_multicast_group *mc;
SBREC_MULTICAST_GROUP_TABLE_FOR_EACH (mc, p_ctx->mc_group_table) {
consider_mc_group(p_ctx->sbrec_port_binding_by_name,
Expand All @@ -2053,7 +2053,7 @@ physical_run(struct physical_ctx *p_ctx,
* encapsulations have metadata about the ingress and egress logical ports.
* VXLAN encapsulations have metadata about the egress logical port only.
* We set MFF_LOG_DATAPATH, MFF_LOG_INPORT, and MFF_LOG_OUTPORT from the
* tunnel key data where possible, then resubmit to table 38 to handle
* tunnel key data where possible, then resubmit to table 41 to handle
* packets to the local hypervisor. */
struct chassis_tunnel *tun;
HMAP_FOR_EACH (tun, hmap_node, p_ctx->chassis_tunnels) {
Expand Down Expand Up @@ -2155,41 +2155,64 @@ physical_run(struct physical_ctx *p_ctx,
*/
add_default_drop_flow(p_ctx, OFTABLE_PHY_TO_LOG, flow_table);

/* Table 37, priority 150.
/* Table 34-36, priority 0.
* ========================
*
* Default resubmit actions for OFTABLE_OUTPUT_LARGE_PKT_* tables.
*/
struct match match;
match_init_catchall(&match);
ofpbuf_clear(&ofpacts);
put_resubmit(OFTABLE_OUTPUT_LARGE_PKT_DETECT, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_OUTPUT_INIT, 0, 0, &match,
&ofpacts, hc_uuid);

match_init_catchall(&match);
ofpbuf_clear(&ofpacts);
put_resubmit(OFTABLE_REMOTE_OUTPUT, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_OUTPUT_LARGE_PKT_DETECT, 0, 0, &match,
&ofpacts, hc_uuid);

match_init_catchall(&match);
ofpbuf_clear(&ofpacts);
put_resubmit(OFTABLE_REMOTE_OUTPUT, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_OUTPUT_LARGE_PKT_PROCESS, 0, 0, &match,
&ofpacts, hc_uuid);

/* Table 40, priority 150.
* =======================
*
* Handles packets received from a VXLAN tunnel which get resubmitted to
* OFTABLE_LOG_INGRESS_PIPELINE due to lack of needed metadata in VXLAN,
* explicitly skip sending back out any tunnels and resubmit to table 38
* explicitly skip sending back out any tunnels and resubmit to table 41
* for local delivery, except packets which have MLF_ALLOW_LOOPBACK bit
* set.
*/
struct match match;
match_init_catchall(&match);
match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0, MLF_RCV_FROM_RAMP,
MLF_RCV_FROM_RAMP | MLF_ALLOW_LOOPBACK);

/* Resubmit to table 38. */
/* Resubmit to table 41. */
ofpbuf_clear(&ofpacts);
put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0,
&match, &ofpacts, hc_uuid);

/* Table 37, priority 150.
/* Table 40, priority 150.
* =======================
*
* Packets that should not be sent to other hypervisors.
*/
match_init_catchall(&match);
match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
MLF_LOCAL_ONLY, MLF_LOCAL_ONLY);
/* Resubmit to table 38. */
/* Resubmit to table 41. */
ofpbuf_clear(&ofpacts);
put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts);
ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0,
&match, &ofpacts, hc_uuid);

/* Table 37, Priority 0.
/* Table 40, Priority 0.
* =======================
*
* Resubmit packets that are not directed at tunnels or part of a
Expand All @@ -2200,18 +2223,18 @@ physical_run(struct physical_ctx *p_ctx,
ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 0, 0, &match,
&ofpacts, hc_uuid);

/* Table 38, priority 0.
/* Table 41, priority 0.
* ======================
*
* Drop packets that do not match previous flows.
*/
add_default_drop_flow(p_ctx, OFTABLE_LOCAL_OUTPUT, flow_table);

/* Table 39, Priority 0.
/* Table 42, Priority 0.
* =======================
*
* Resubmit packets that don't output to the ingress port (already checked
* in table 38) to the logical egress pipeline, clearing the logical
* in table 41) to the logical egress pipeline, clearing the logical
* registers (for consistent behavior with packets that get tunneled). */
match_init_catchall(&match);
ofpbuf_clear(&ofpacts);
Expand Down
8 changes: 4 additions & 4 deletions controller/pinctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ set_actions_and_enqueue_msg(struct rconn *swconn,
}

/* Forwards a packet to 'out_port_key' even if that's on a remote
* hypervisor, i.e., the packet is re-injected in table OFTABLE_REMOTE_OUTPUT.
* hypervisor, i.e., the packet is re-injected in table OFTABLE_OUTPUT_INIT.
*/
static void
pinctrl_forward_pkt(struct rconn *swconn, int64_t dp_key,
Expand All @@ -647,7 +647,7 @@ pinctrl_forward_pkt(struct rconn *swconn, int64_t dp_key,

struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
resubmit->in_port = OFPP_CONTROLLER;
resubmit->table_id = OFTABLE_REMOTE_OUTPUT;
resubmit->table_id = OFTABLE_OUTPUT_INIT;

struct ofputil_packet_out po = {
.packet = dp_packet_data(pkt),
Expand Down Expand Up @@ -873,7 +873,7 @@ pinctrl_parse_dhcpv6_advt(struct rconn *swconn, const struct flow *ip_flow,
0, 32, &ofpacts);
struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
resubmit->in_port = OFPP_CONTROLLER;
resubmit->table_id = OFTABLE_REMOTE_OUTPUT;
resubmit->table_id = OFTABLE_OUTPUT_INIT;

struct ofputil_packet_out po = {
.packet = dp_packet_data(&packet),
Expand Down Expand Up @@ -1471,7 +1471,7 @@ OVS_REQUIRES(pinctrl_mutex)

struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
resubmit->in_port = OFPP_CONTROLLER;
resubmit->table_id = OFTABLE_REMOTE_OUTPUT;
resubmit->table_id = OFTABLE_OUTPUT_INIT;

struct packet_data *pd = ovn_packet_data_create(ofpacts, pkt_in);
ovn_buffered_packets_packet_data_enqueue(bp, pd);
Expand Down

0 comments on commit 740f23c

Please sign in to comment.