From 94da21fe59eda817e3ee3c81497436ef34ac9bea Mon Sep 17 00:00:00 2001 From: "hailun.huang" Date: Mon, 11 Sep 2023 07:24:44 +0000 Subject: [PATCH] Add time exceeded flow for fip Add "ip4.src == " to match for distinguish between external router gateway and floatingIP to handle time exceeded packet. Signed-off-by: Huanghailun --- northd/northd.c | 47 +++++++++++++++++++++++++++++++++++------ northd/ovn-northd.8.xml | 22 +++++++++++++++++++ 2 files changed, 63 insertions(+), 6 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 3eaa43f07a..9044a40830 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -13994,6 +13994,43 @@ build_lrouter_arp_nd_for_datapath(struct ovn_datapath *od, } } +/* Logical router ingress table 3: IP Input for IPv4. */ +static void +add_time_exceeded_flow_for_dnat_and_snat(struct ovn_port *op, + struct hmap *lflows, struct ds *ip_ds, + struct ds *match, struct ds *actions, + const struct shash *meter_groups) +{ + if (is_l3dgw_port(op)) { + for (int i = 0; i < op->od->nbr->n_nat; i++) { + ds_clear(match); + ds_clear(actions); + ds_clear(ip_ds); + struct ovn_nat *nat_entry = &op->od->nat_entries[i]; + if (!strcmp(nat_entry->nb->type, "dnat_and_snat")) { + ds_put_format(match, "ip4.src == %s && ", nat_entry->nb->external_ip); + ds_put_cstr(ip_ds, "ip4.dst <-> ip4.src"); + ds_put_format(match, + "inport == %s && ip4 && " + "ip.ttl == {0, 1} && !ip.later_frag", op->json_key); + ds_put_format(actions, + "icmp4 {" + "eth.dst <-> eth.src; " + "icmp4.type = 11; /* Time exceeded */ " + "icmp4.code = 0; /* TTL exceeded in transit */ " + "%s ; ip.ttl = 254; " + "outport = %s; flags.loopback = 1; output; };", + ds_cstr(ip_ds), op->json_key); + ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, + 32, ds_cstr(match), ds_cstr(actions), NULL, + copp_meter_get(COPP_ICMP4_ERR, op->od->nbr->copp, + meter_groups), + &op->nbrp->header_); + } + } + } +} + /* Logical router ingress table 3: IP Input for IPv4. */ static void build_lrouter_ipv4_ip_input(struct ovn_port *op, @@ -14044,16 +14081,14 @@ build_lrouter_ipv4_ip_input(struct ovn_port *op, /* ICMP time exceeded */ struct ds ip_ds = DS_EMPTY_INITIALIZER; + add_time_exceeded_flow_for_dnat_and_snat(op, lflows, &ip_ds, + match, actions, meter_groups); for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) { ds_clear(match); ds_clear(actions); ds_clear(&ip_ds); - if (is_l3dgw_port(op)) { - ds_put_cstr(&ip_ds, "ip4.dst <-> ip4.src"); - } else { - ds_put_format(&ip_ds, "ip4.dst = ip4.src; ip4.src = %s", - op->lrp_networks.ipv4_addrs[i].addr_s); - } + ds_put_format(&ip_ds, "ip4.dst = ip4.src; ip4.src = %s", + op->lrp_networks.ipv4_addrs[i].addr_s); ds_put_format(match, "inport == %s && ip4 && " "ip.ttl == {0, 1} && !ip.later_frag", op->json_key); diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml index df8ed67505..9049f110aa 100644 --- a/northd/ovn-northd.8.xml +++ b/northd/ovn-northd.8.xml @@ -3252,6 +3252,28 @@ nd.tll = external_mac; multicast packets whose TTL has expired without sending ICMP time exceeded. +
  • +

    + Distinguish ICMP time exceeded for floating ip and router gateway ip. + For each router port P, whose IP address is A, + with NAT table records of type dnat_and_snat N, whose + external_ip is B. A priority-32 flow with match + ip4.src == B && inport == + P && ip.ttl == {0, 1} && !ip.later_frag + matches packets whose TTL has expired, with the following + actions to send an ICMP time exceeded reply for IPv4 respectively: +

    + +
    +icmp4 {
    +    icmp4.type = 11; /* Time exceeded. */
    +    icmp4.code = 0;  /* TTL exceeded in transit. */
    +    ip4.dst <-> ip4.src;
    +    ip.ttl = 254;
    +    next;
    +};
    +        
    +