[ovs-dev] [RFC ovn 3/5] ovn-northd: Add CoPP policies for flows that punt packets to ovn-controller.
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Sat Apr 24 10:39:33 UTC 2021
From: Dumitru Ceara <dceara at redhat.com>
Change the ovn-northd implementation to set the new 'controller_meter'
field for flows that need to punt packets to ovn-controller. For protocols
that get per port logical flows, any potential per port CoPP policies
take precedence over switch/router CoPP policies.
Protocol packets for which CoPP is enforced when sending packets to
ovn-controller (if configured):
- ARP
- ND_NS
- ND_NA
- ND_RA
- DNS
- IGMP
- packets that require ARP resolution before forwarding
- packets that require ND_NS before forwarding
- packets that need to be replied to with ICMP Errors
- packets that need to be replied to with TCP RST
- packets that need to be replied to with DHCP_OPTS
- BFD
Co-authored-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
Signed-off-by: Dumitru Ceara <dceara at redhat.com>
---
northd/ovn-northd.c | 406 +++++++++++++++++++++++++++++---------------
1 file changed, 269 insertions(+), 137 deletions(-)
diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c
index 2e9c7de22..3824ce3f6 100644
--- a/northd/ovn-northd.c
+++ b/northd/ovn-northd.c
@@ -4174,9 +4174,14 @@ ovn_lflow_add_at(struct hmap *lflow_map, struct ovn_datapath *od,
ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, false, \
NULL, STAGE_HINT, OVS_SOURCE_LOCATOR)
-#define ovn_lflow_add_unique(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS) \
+#define ovn_lflow_add_unique__(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \
+ CTRL_METER) \
ovn_lflow_add_at(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, false, \
- NULL, NULL, OVS_SOURCE_LOCATOR)
+ CTRL_METER, NULL, OVS_SOURCE_LOCATOR)
+
+#define ovn_lflow_add_unique(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS) \
+ ovn_lflow_add_unique__(LFLOW_MAP, OD, STAGE, PRIORITY, MATCH, ACTIONS, \
+ NULL)
static struct ovn_lflow *
ovn_lflow_find(struct hmap *lflows, struct ovn_datapath *od,
@@ -5429,9 +5434,12 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows,
"reject { "
"/* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ "
"outport <-> inport; %s };", next_action);
- ovn_lflow_add_with_hint(lflows, od, stage,
- acl->priority + OVN_ACL_PRI_OFFSET,
- ds_cstr(&match), ds_cstr(&actions), stage_hint);
+ ovn_lflow_add_with_hint__(lflows, od, stage,
+ acl->priority + OVN_ACL_PRI_OFFSET,
+ ds_cstr(&match), ds_cstr(&actions),
+ copp_meter_get(COPP_TCP_RESET, od->nbs->copp,
+ meter_groups),
+ stage_hint);
free(next_action);
ds_destroy(&match);
@@ -6603,6 +6611,7 @@ static void
build_dhcpv4_options_flows(struct ovn_port *op,
struct lport_addresses *lsp_addrs,
const char *json_key, bool is_external,
+ struct shash *meter_groups,
struct hmap *lflows)
{
struct ds match = DS_EMPTY_INITIALIZER;
@@ -6626,11 +6635,15 @@ build_dhcpv4_options_flows(struct ovn_port *op,
op->json_key);
}
- ovn_lflow_add_with_hint(lflows, op->od,
- S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
- ds_cstr(&options_action),
- &op->nbsp->dhcpv4_options->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od,
+ S_SWITCH_IN_DHCP_OPTIONS, 100,
+ ds_cstr(&match),
+ ds_cstr(&options_action),
+ copp_port_meter_get(COPP_DHCPV4_OPTS,
+ op->nbsp->copp,
+ op->od->nbs->copp,
+ meter_groups),
+ &op->nbsp->dhcpv4_options->header_);
ds_clear(&match);
/* Allow ip4.src = OFFER_IP and
* ip4.dst = {SERVER_IP, 255.255.255.255} for the below
@@ -6650,11 +6663,15 @@ build_dhcpv4_options_flows(struct ovn_port *op,
op->json_key);
}
- ovn_lflow_add_with_hint(lflows, op->od,
- S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
- ds_cstr(&options_action),
- &op->nbsp->dhcpv4_options->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od,
+ S_SWITCH_IN_DHCP_OPTIONS, 100,
+ ds_cstr(&match),
+ ds_cstr(&options_action),
+ copp_port_meter_get(COPP_DHCPV4_OPTS,
+ op->nbsp->copp,
+ op->od->nbs->copp,
+ meter_groups),
+ &op->nbsp->dhcpv4_options->header_);
ds_clear(&match);
/* If REGBIT_DHCP_OPTS_RESULT is set, it means the
@@ -6688,6 +6705,7 @@ static void
build_dhcpv6_options_flows(struct ovn_port *op,
struct lport_addresses *lsp_addrs,
const char *json_key, bool is_external,
+ struct shash *meter_groups,
struct hmap *lflows)
{
struct ds match = DS_EMPTY_INITIALIZER;
@@ -6710,11 +6728,15 @@ build_dhcpv6_options_flows(struct ovn_port *op,
op->json_key);
}
- ovn_lflow_add_with_hint(lflows, op->od,
- S_SWITCH_IN_DHCP_OPTIONS, 100,
- ds_cstr(&match),
- ds_cstr(&options_action),
- &op->nbsp->dhcpv6_options->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od,
+ S_SWITCH_IN_DHCP_OPTIONS, 100,
+ ds_cstr(&match),
+ ds_cstr(&options_action),
+ copp_port_meter_get(COPP_DHCPV6_OPTS,
+ op->nbsp->copp,
+ op->od->nbs->copp,
+ meter_groups),
+ &op->nbsp->dhcpv6_options->header_);
/* If REGBIT_DHCP_OPTS_RESULT is set to 1, it means the
* put_dhcpv6_opts action is successful */
@@ -6909,6 +6931,7 @@ static void
build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op,
struct hmap *lflows,
struct hmap *ports,
+ struct shash *meter_groups,
struct ds *actions,
struct ds *match)
{
@@ -7050,11 +7073,15 @@ build_lswitch_arp_nd_responder_known_ips(struct ovn_port *op,
op->lsp_addrs[i].ipv6_addrs[j].addr_s,
op->lsp_addrs[i].ipv6_addrs[j].addr_s,
op->lsp_addrs[i].ea_s);
- ovn_lflow_add_with_hint(lflows, op->od,
- S_SWITCH_IN_ARP_ND_RSP, 50,
- ds_cstr(match),
- ds_cstr(actions),
- &op->nbsp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od,
+ S_SWITCH_IN_ARP_ND_RSP, 50,
+ ds_cstr(match),
+ ds_cstr(actions),
+ copp_port_meter_get(COPP_ND_NA,
+ op->nbsp->copp,
+ op->od->nbs->copp,
+ meter_groups),
+ &op->nbsp->header_);
/* Do not reply to a solicitation from the port that owns
* the address (otherwise DAD detection will fail). */
@@ -7132,7 +7159,8 @@ build_lswitch_arp_nd_service_monitor(struct ovn_northd_lb *lb,
* priority 100 flows. */
static void
build_lswitch_dhcp_options_and_response(struct ovn_port *op,
- struct hmap *lflows)
+ struct hmap *lflows,
+ struct shash *meter_groups)
{
if (op->nbsp) {
if (!lsp_is_enabled(op->nbsp) || lsp_is_router(op->nbsp)) {
@@ -7161,17 +7189,17 @@ build_lswitch_dhcp_options_and_response(struct ovn_port *op,
build_dhcpv4_options_flows(
op, &op->lsp_addrs[i],
op->od->localnet_ports[j]->json_key, is_external,
- lflows);
+ meter_groups, lflows);
build_dhcpv6_options_flows(
op, &op->lsp_addrs[i],
op->od->localnet_ports[j]->json_key, is_external,
- lflows);
+ meter_groups, lflows);
}
} else {
build_dhcpv4_options_flows(op, &op->lsp_addrs[i], op->json_key,
- is_external, lflows);
+ is_external, meter_groups, lflows);
build_dhcpv6_options_flows(op, &op->lsp_addrs[i], op->json_key,
- is_external, lflows);
+ is_external, meter_groups, lflows);
}
}
}
@@ -7201,13 +7229,19 @@ build_lswitch_dhcp_and_dns_defaults(struct ovn_datapath *od,
*/
static void
build_lswitch_dns_lookup_and_response(struct ovn_datapath *od,
- struct hmap *lflows)
+ struct hmap *lflows,
+ struct shash *meter_groups)
{
if (od->nbs && ls_has_dns_records(od->nbs)) {
ovn_lflow_add(lflows, od, S_SWITCH_IN_DNS_LOOKUP, 100,
"udp.dst == 53",
REGBIT_DNS_LOOKUP_RESULT" = dns_lookup(); next;");
+ ovn_lflow_add_ctrl(lflows, od, S_SWITCH_IN_DNS_LOOKUP, 100,
+ "udp.dst == 53",
+ REGBIT_DNS_LOOKUP_RESULT" = dns_lookup(); next;",
+ copp_meter_get(COPP_DNS, od->nbs->copp,
+ meter_groups));
const char *dns_action = "eth.dst <-> eth.src; ip4.src <-> ip4.dst; "
"udp.dst = udp.src; udp.src = 53; outport = inport; "
"flags.loopback = 1; output;";
@@ -7244,7 +7278,8 @@ build_lswitch_external_port(struct ovn_port *op,
static void
build_lswitch_destination_lookup_bmcast(struct ovn_datapath *od,
struct hmap *lflows,
- struct ds *actions)
+ struct ds *actions,
+ struct shash *meter_groups)
{
if (od->nbs) {
@@ -7265,12 +7300,16 @@ build_lswitch_destination_lookup_bmcast(struct ovn_datapath *od,
}
ds_put_cstr(actions, "igmp;");
/* Punt IGMP traffic to controller. */
- ovn_lflow_add_unique(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
- "ip4 && ip.proto == 2", ds_cstr(actions));
+ ovn_lflow_add_unique__(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
+ "ip4 && ip.proto == 2", ds_cstr(actions),
+ copp_meter_get(COPP_IGMP, od->nbs->copp,
+ meter_groups));
/* Punt MLD traffic to controller. */
- ovn_lflow_add_unique(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
- "mldv1 || mldv2", ds_cstr(actions));
+ ovn_lflow_add_unique__(lflows, od, S_SWITCH_IN_L2_LKUP, 100,
+ "mldv1 || mldv2", ds_cstr(actions),
+ copp_meter_get(COPP_IGMP, od->nbs->copp,
+ meter_groups));
/* Flood all IP multicast traffic destined to 224.0.0.X to all
* ports - RFC 4541, section 2.1.2, item 2.
@@ -9097,7 +9136,7 @@ build_lrouter_nd_flow(struct ovn_datapath *od, struct ovn_port *op,
const char *sn_ip_address, const char *eth_addr,
struct ds *extra_match, bool drop, uint16_t priority,
const struct ovsdb_idl_row *hint,
- struct hmap *lflows)
+ struct hmap *lflows, struct shash *meter_groups)
{
struct ds match = DS_EMPTY_INITIALIZER;
struct ds actions = DS_EMPTY_INITIALIZER;
@@ -9119,6 +9158,8 @@ build_lrouter_nd_flow(struct ovn_datapath *od, struct ovn_port *op,
if (drop) {
ds_put_format(&actions, "drop;");
+ ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_INPUT, priority,
+ ds_cstr(&match), ds_cstr(&actions), hint);
} else {
ds_put_format(&actions,
"%s { "
@@ -9135,11 +9176,13 @@ build_lrouter_nd_flow(struct ovn_datapath *od, struct ovn_port *op,
ip_address,
ip_address,
eth_addr);
+ ovn_lflow_add_with_hint__(lflows, od, S_ROUTER_IN_IP_INPUT, priority,
+ ds_cstr(&match), ds_cstr(&actions),
+ copp_meter_get(COPP_ND_NA, od->nbr->copp,
+ meter_groups),
+ hint);
}
- ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_IP_INPUT, priority,
- ds_cstr(&match), ds_cstr(&actions), hint);
-
ds_destroy(&match);
ds_destroy(&actions);
}
@@ -9147,7 +9190,8 @@ build_lrouter_nd_flow(struct ovn_datapath *od, struct ovn_port *op,
static void
build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od,
struct ovn_nat *nat_entry,
- struct hmap *lflows)
+ struct hmap *lflows,
+ struct shash *meter_groups)
{
struct lport_addresses *ext_addrs = &nat_entry->ext_addrs;
const struct nbrec_nat *nat = nat_entry->nb;
@@ -9157,7 +9201,7 @@ build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od,
ext_addrs->ipv6_addrs[0].addr_s,
ext_addrs->ipv6_addrs[0].sn_addr_s,
REG_INPORT_ETH_ADDR, NULL, false, 90,
- &nat->header_, lflows);
+ &nat->header_, lflows, meter_groups);
} else {
build_lrouter_arp_flow(od, NULL,
ext_addrs->ipv4_addrs[0].addr_s,
@@ -9169,7 +9213,8 @@ build_lrouter_nat_arp_nd_flow(struct ovn_datapath *od,
static void
build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
struct ovn_nat *nat_entry,
- struct hmap *lflows)
+ struct hmap *lflows,
+ struct shash *meter_groups)
{
struct lport_addresses *ext_addrs = &nat_entry->ext_addrs;
const struct nbrec_nat *nat = nat_entry->nb;
@@ -9212,12 +9257,12 @@ build_lrouter_port_nat_arp_nd_flow(struct ovn_port *op,
ext_addrs->ipv6_addrs[0].addr_s,
ext_addrs->ipv6_addrs[0].sn_addr_s,
mac_s, &match, false, 92,
- &nat->header_, lflows);
+ &nat->header_, lflows, meter_groups);
build_lrouter_nd_flow(op->od, op, "nd_na",
ext_addrs->ipv6_addrs[0].addr_s,
ext_addrs->ipv6_addrs[0].sn_addr_s,
mac_s, NULL, true, 91,
- &nat->header_, lflows);
+ &nat->header_, lflows, meter_groups);
} else {
build_lrouter_arp_flow(op->od, op,
ext_addrs->ipv4_addrs[0].addr_s,
@@ -9390,7 +9435,8 @@ build_lrouter_force_snat_flows_op(struct ovn_port *op,
}
static void
-build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op)
+build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op,
+ struct shash *meter_groups)
{
if (!op->has_bfd) {
return;
@@ -9409,9 +9455,12 @@ build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op)
ds_clear(&match);
ds_put_format(&match, "ip4.dst == %s && udp.dst == 3784",
ds_cstr(&ip_list));
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "handle_bfd_msg(); ",
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
+ ds_cstr(&match), "handle_bfd_msg(); ",
+ copp_port_meter_get(COPP_BFD, op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
if (op->lrp_networks.n_ipv6_addrs) {
ds_clear(&ip_list);
@@ -9426,9 +9475,12 @@ build_lrouter_bfd_flows(struct hmap *lflows, struct ovn_port *op)
ds_clear(&match);
ds_put_format(&match, "ip6.dst == %s && udp.dst == 3784",
ds_cstr(&ip_list));
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
- ds_cstr(&match), "handle_bfd_msg(); ",
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, 110,
+ ds_cstr(&match), "handle_bfd_msg(); ",
+ copp_port_meter_get(COPP_BFD, op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
ds_destroy(&ip_list);
@@ -9508,7 +9560,8 @@ build_adm_ctrl_flows_for_lrouter_port(
static void
build_neigh_learning_flows_for_lrouter(
struct ovn_datapath *od, struct hmap *lflows,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
if (od->nbr) {
@@ -9588,14 +9641,20 @@ build_neigh_learning_flows_for_lrouter(
ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 100,
ds_cstr(match), "next;");
- ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
- "arp", "put_arp(inport, arp.spa, arp.sha); next;");
+ ovn_lflow_add_ctrl(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
+ "arp", "put_arp(inport, arp.spa, arp.sha); next;",
+ copp_meter_get(COPP_ARP, od->nbr->copp,
+ meter_groups));
- ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
- "nd_na", "put_nd(inport, nd.target, nd.tll); next;");
+ ovn_lflow_add_ctrl(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
+ "nd_na", "put_nd(inport, nd.target, nd.tll); next;",
+ copp_meter_get(COPP_ND_NA, od->nbr->copp,
+ meter_groups));
- ovn_lflow_add(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
- "nd_ns", "put_nd(inport, ip6.src, nd.sll); next;");
+ ovn_lflow_add_ctrl(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90,
+ "nd_ns", "put_nd(inport, ip6.src, nd.sll); next;",
+ copp_meter_get(COPP_ND_NS, od->nbr->copp,
+ meter_groups));
}
}
@@ -9670,7 +9729,8 @@ build_neigh_learning_flows_for_lrouter_port(
static void
build_ND_RA_flows_for_lrouter_port(
struct ovn_port *op, struct hmap *lflows,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
if (!op->nbrp || op->nbrp->peer || !op->peer) {
return;
@@ -9763,9 +9823,13 @@ build_ND_RA_flows_for_lrouter_port(
if (add_rs_response_flow) {
ds_put_cstr(actions, "); next;");
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_ND_RA_OPTIONS,
- 50, ds_cstr(match), ds_cstr(actions),
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_ND_RA_OPTIONS,
+ 50, ds_cstr(match), ds_cstr(actions),
+ copp_port_meter_get(COPP_ND_RA_OPTS,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
ds_clear(actions);
ds_clear(match);
ds_put_format(match, "inport == %s && ip6.dst == ff02::2 && "
@@ -10388,7 +10452,8 @@ static void
build_check_pkt_len_flows_for_lrouter(
struct ovn_datapath *od, struct hmap *lflows,
struct hmap *ports,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
if (od->nbr) {
@@ -10450,10 +10515,15 @@ build_check_pkt_len_flows_for_lrouter(
rp->lrp_networks.ipv4_addrs[0].addr_s,
gw_mtu,
ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
- ovn_lflow_add_with_hint(lflows, od,
- S_ROUTER_IN_LARGER_PKTS, 50,
- ds_cstr(match), ds_cstr(actions),
- &rp->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, od,
+ S_ROUTER_IN_LARGER_PKTS, 50,
+ ds_cstr(match), ds_cstr(actions),
+ copp_port_meter_get(
+ COPP_ICMP4_ERR,
+ rp->nbrp->copp,
+ rp->od->nbr->copp,
+ meter_groups),
+ &rp->nbrp->header_);
}
if (rp->lrp_networks.ipv6_addrs) {
@@ -10479,10 +10549,15 @@ build_check_pkt_len_flows_for_lrouter(
rp->lrp_networks.ipv6_addrs[0].addr_s,
gw_mtu,
ovn_stage_get_table(S_ROUTER_IN_ADMISSION));
- ovn_lflow_add_with_hint(lflows, od,
- S_ROUTER_IN_LARGER_PKTS, 50,
- ds_cstr(match), ds_cstr(actions),
- &rp->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, od,
+ S_ROUTER_IN_LARGER_PKTS, 50,
+ ds_cstr(match), ds_cstr(actions),
+ copp_port_meter_get(
+ COPP_ICMP6_ERR,
+ rp->nbrp->copp,
+ rp->od->nbr->copp,
+ meter_groups),
+ &rp->nbrp->header_);
}
}
}
@@ -10537,7 +10612,8 @@ build_gateway_redirect_flows_for_lrouter(
static void
build_arp_request_flows_for_lrouter(
struct ovn_datapath *od, struct hmap *lflows,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
if (od->nbr) {
for (int i = 0; i < od->nbr->n_static_routes; i++) {
@@ -10574,26 +10650,33 @@ build_arp_request_flows_for_lrouter(
"};", ETH_ADDR_ARGS(eth_dst), sn_addr_s,
route->nexthop);
- ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200,
- ds_cstr(match), ds_cstr(actions),
- &route->header_);
- }
-
- ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100,
- "eth.dst == 00:00:00:00:00:00 && ip4",
- "arp { "
- "eth.dst = ff:ff:ff:ff:ff:ff; "
- "arp.spa = " REG_SRC_IPV4 "; "
- "arp.tpa = " REG_NEXT_HOP_IPV4 "; "
- "arp.op = 1; " /* ARP request */
- "output; "
- "};");
- ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100,
- "eth.dst == 00:00:00:00:00:00 && ip6",
- "nd_ns { "
- "nd.target = " REG_NEXT_HOP_IPV6 "; "
- "output; "
- "};");
+ ovn_lflow_add_with_hint__(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200,
+ ds_cstr(match), ds_cstr(actions),
+ copp_meter_get(COPP_ND_NS_RESOLVE,
+ od->nbr->copp,
+ meter_groups),
+ &route->header_);
+ }
+
+ ovn_lflow_add_ctrl(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100,
+ "eth.dst == 00:00:00:00:00:00 && ip4",
+ "arp { "
+ "eth.dst = ff:ff:ff:ff:ff:ff; "
+ "arp.spa = " REG_SRC_IPV4 "; "
+ "arp.tpa = " REG_NEXT_HOP_IPV4 "; "
+ "arp.op = 1; " /* ARP request */
+ "output; "
+ "};",
+ copp_meter_get(COPP_ARP_RESOLVE, od->nbr->copp,
+ meter_groups));
+ ovn_lflow_add_ctrl(lflows, od, S_ROUTER_IN_ARP_REQUEST, 100,
+ "eth.dst == 00:00:00:00:00:00 && ip6",
+ "nd_ns { "
+ "nd.target = " REG_NEXT_HOP_IPV6 "; "
+ "output; "
+ "};",
+ copp_meter_get(COPP_ND_NS_RESOLVE, od->nbr->copp,
+ meter_groups));
ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 0, "1", "output;");
}
}
@@ -10724,7 +10807,8 @@ build_dhcpv6_reply_flows_for_lrouter_port(
static void
build_ipv6_input_flows_for_lrouter_port(
struct ovn_port *op, struct hmap *lflows,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
if (op->nbrp && (!op->derived)) {
/* No ingress packets are accepted on a chassisredirect
@@ -10767,7 +10851,7 @@ build_ipv6_input_flows_for_lrouter_port(
op->lrp_networks.ipv6_addrs[i].addr_s,
op->lrp_networks.ipv6_addrs[i].sn_addr_s,
REG_INPORT_ETH_ADDR, match, false, 90,
- &op->nbrp->header_, lflows);
+ &op->nbrp->header_, lflows, meter_groups);
}
/* UDP/TCP/SCTP port unreachable */
@@ -10782,9 +10866,14 @@ build_ipv6_input_flows_for_lrouter_port(
"eth.dst <-> eth.src; "
"ip6.dst <-> ip6.src; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 80, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 80, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_TCP_RESET,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
ds_clear(match);
ds_put_format(match,
@@ -10809,9 +10898,14 @@ build_ipv6_input_flows_for_lrouter_port(
"icmp6.type = 1; "
"icmp6.code = 4; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 80, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 80, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_ICMP6_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
ds_clear(match);
ds_put_format(match,
@@ -10824,9 +10918,14 @@ build_ipv6_input_flows_for_lrouter_port(
"icmp6.type = 1; "
"icmp6.code = 3; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 70, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 70, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_ICMP6_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
}
@@ -10857,9 +10956,13 @@ build_ipv6_input_flows_for_lrouter_port(
"icmp6.code = 0; /* TTL exceeded in transit */ "
"next; };",
op->lrp_networks.ipv6_addrs[i].addr_s);
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 40,
- ds_cstr(match), ds_cstr(actions),
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, 40,
+ ds_cstr(match), ds_cstr(actions),
+ copp_port_meter_get(COPP_ICMP6_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
}
@@ -10867,7 +10970,8 @@ build_ipv6_input_flows_for_lrouter_port(
static void
build_lrouter_arp_nd_for_datapath(struct ovn_datapath *od,
- struct hmap *lflows)
+ struct hmap *lflows,
+ struct shash *meter_groups)
{
if (od->nbr) {
@@ -10893,7 +10997,7 @@ build_lrouter_arp_nd_for_datapath(struct ovn_datapath *od,
if (!strcmp(nat_entry->nb->type, "snat")) {
continue;
}
- build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows);
+ build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows, meter_groups);
}
/* Now handle SNAT entries too, one per unique SNAT IP. */
@@ -10908,7 +11012,7 @@ build_lrouter_arp_nd_for_datapath(struct ovn_datapath *od,
struct ovn_nat *nat_entry =
CONTAINER_OF(ovs_list_front(&snat_ip->snat_entries),
struct ovn_nat, ext_addr_list_node);
- build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows);
+ build_lrouter_nat_arp_nd_flow(od, nat_entry, lflows, meter_groups);
}
}
}
@@ -10917,7 +11021,8 @@ build_lrouter_arp_nd_for_datapath(struct ovn_datapath *od,
static void
build_lrouter_ipv4_ip_input(struct ovn_port *op,
struct hmap *lflows,
- struct ds *match, struct ds *actions)
+ struct ds *match, struct ds *actions,
+ struct shash *meter_groups)
{
/* No ingress packets are accepted on a chassisredirect
* port, so no need to program flows for that port. */
@@ -10955,7 +11060,7 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
}
/* BFD msg handling */
- build_lrouter_bfd_flows(lflows, op);
+ build_lrouter_bfd_flows(lflows, op, meter_groups);
/* ICMP time exceeded */
for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) {
@@ -10975,9 +11080,13 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
"ip.ttl = 255; "
"next; };",
op->lrp_networks.ipv4_addrs[i].addr_s);
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT, 40,
- ds_cstr(match), ds_cstr(actions),
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, 40,
+ ds_cstr(match), ds_cstr(actions),
+ copp_port_meter_get(COPP_ICMP4_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
/* ARP reply. These flows reply to ARP requests for the router's own
@@ -11051,7 +11160,8 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
build_lrouter_nd_flow(op->od, op, "nd_na",
ip_address, NULL, REG_INPORT_ETH_ADDR,
- match, false, 90, NULL, lflows);
+ match, false, 90, NULL,
+ lflows, meter_groups);
}
sset_destroy(&all_ips_v4);
@@ -11072,9 +11182,14 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
"icmp4.type = 3; "
"icmp4.code = 3; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 80, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 80, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_ICMP4_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
ds_clear(match);
ds_put_format(match,
@@ -11084,9 +11199,14 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
"eth.dst <-> eth.src; "
"ip4.dst <-> ip4.src; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 80, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 80, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_TCP_RESET,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
ds_clear(match);
ds_put_format(match,
@@ -11111,9 +11231,14 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
"icmp4.type = 3; "
"icmp4.code = 2; "
"next; };";
- ovn_lflow_add_with_hint(lflows, op->od, S_ROUTER_IN_IP_INPUT,
- 70, ds_cstr(match), action,
- &op->nbrp->header_);
+ ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT,
+ 70, ds_cstr(match), action,
+ copp_port_meter_get(
+ COPP_ICMP4_ERR,
+ op->nbrp->copp,
+ op->od->nbr->copp,
+ meter_groups),
+ &op->nbrp->header_);
}
}
@@ -11157,7 +11282,8 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
if (!strcmp(nat_entry->nb->type, "snat")) {
continue;
}
- build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows);
+ build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows,
+ meter_groups);
}
/* Now handle SNAT entries too, one per unique SNAT IP. */
@@ -11172,7 +11298,8 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op,
struct ovn_nat *nat_entry =
CONTAINER_OF(ovs_list_front(&snat_ip->snat_entries),
struct ovn_nat, ext_addr_list_node);
- build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows);
+ build_lrouter_port_nat_arp_nd_flow(op, nat_entry, lflows,
+ meter_groups);
}
}
}
@@ -11853,15 +11980,16 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od,
build_lswitch_input_port_sec_od(od, lsi->lflows);
build_lswitch_learn_fdb_od(od, lsi->lflows);
build_lswitch_arp_nd_responder_default(od, lsi->lflows);
- build_lswitch_dns_lookup_and_response(od, lsi->lflows);
+ build_lswitch_dns_lookup_and_response(od, lsi->lflows, lsi->meter_groups);
build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows);
- build_lswitch_destination_lookup_bmcast(od, lsi->lflows, &lsi->actions);
+ build_lswitch_destination_lookup_bmcast(od, lsi->lflows, &lsi->actions,
+ lsi->meter_groups);
build_lswitch_output_port_sec_od(od, lsi->lflows);
/* Build Logical Router Flows. */
build_adm_ctrl_flows_for_lrouter(od, lsi->lflows);
build_neigh_learning_flows_for_lrouter(od, lsi->lflows, &lsi->match,
- &lsi->actions);
+ &lsi->actions, lsi->meter_groups);
build_ND_RA_flows_for_lrouter(od, lsi->lflows);
build_static_route_flows_for_lrouter(od, lsi->lflows, lsi->ports,
lsi->bfd_connections);
@@ -11870,13 +11998,14 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od,
build_ingress_policy_flows_for_lrouter(od, lsi->lflows, lsi->ports);
build_arp_resolve_flows_for_lrouter(od, lsi->lflows);
build_check_pkt_len_flows_for_lrouter(od, lsi->lflows, lsi->ports,
- &lsi->match, &lsi->actions);
+ &lsi->match, &lsi->actions,
+ lsi->meter_groups);
build_gateway_redirect_flows_for_lrouter(od, lsi->lflows, &lsi->match,
&lsi->actions);
build_arp_request_flows_for_lrouter(od, lsi->lflows, &lsi->match,
- &lsi->actions);
+ &lsi->actions, lsi->meter_groups);
build_misc_local_traffic_drop_flows_for_lrouter(od, lsi->lflows);
- build_lrouter_arp_nd_for_datapath(od, lsi->lflows);
+ build_lrouter_arp_nd_for_datapath(od, lsi->lflows, lsi->meter_groups);
build_lrouter_nat_defrag_and_lb(od, lsi->lflows, lsi->meter_groups,
lsi->lbs, &lsi->match, &lsi->actions);
}
@@ -11896,9 +12025,11 @@ build_lswitch_and_lrouter_iterate_by_op(struct ovn_port *op,
&lsi->match);
build_lswitch_arp_nd_responder_known_ips(op, lsi->lflows,
lsi->ports,
+ lsi->meter_groups,
&lsi->actions,
&lsi->match);
- build_lswitch_dhcp_options_and_response(op, lsi->lflows);
+ build_lswitch_dhcp_options_and_response(op, lsi->lflows,
+ lsi->meter_groups);
build_lswitch_external_port(op, lsi->lflows);
build_lswitch_ip_unicast_lookup(op, lsi->lflows, lsi->mcgroups,
&lsi->actions, &lsi->match);
@@ -11912,16 +12043,17 @@ build_lswitch_and_lrouter_iterate_by_op(struct ovn_port *op,
&lsi->actions);
build_ip_routing_flows_for_lrouter_port(op, lsi->lflows);
build_ND_RA_flows_for_lrouter_port(op, lsi->lflows, &lsi->match,
- &lsi->actions);
+ &lsi->actions, lsi->meter_groups);
build_arp_resolve_flows_for_lrouter_port(op, lsi->lflows, lsi->ports,
&lsi->match, &lsi->actions);
build_egress_delivery_flows_for_lrouter_port(op, lsi->lflows, &lsi->match,
&lsi->actions);
build_dhcpv6_reply_flows_for_lrouter_port(op, lsi->lflows, &lsi->match);
build_ipv6_input_flows_for_lrouter_port(op, lsi->lflows,
- &lsi->match, &lsi->actions);
+ &lsi->match, &lsi->actions,
+ lsi->meter_groups);
build_lrouter_ipv4_ip_input(op, lsi->lflows,
- &lsi->match, &lsi->actions);
+ &lsi->match, &lsi->actions, lsi->meter_groups);
build_lrouter_force_snat_flows_op(op, lsi->lflows, &lsi->match,
&lsi->actions);
}
--
2.30.2
More information about the dev
mailing list