<p>
UDP port unreachable. Priority-80 flows generate ICMP port
unreachable messages in reply to UDP datagrams directed to the
- router's IP address. The logical router doesn't accept any UDP
- traffic so it always generates such a reply.
+ router's IP address, except in the special case of gateways,
+ which accept traffic directed to a router IP for load balancing
+ and NAT purposes.
</p>
<p>
<li>
<p>
- TCP reset. Priority-80 flows generate TCP reset messages in reply to
- TCP datagrams directed to the router's IP address. The logical
- router doesn't accept any TCP traffic so it always generates such a
- reply.
+ TCP reset. Priority-80 flows generate TCP reset messages in reply
+ to TCP datagrams directed to the router's IP address, except in
+ the special case of gateways, which accept traffic directed to a
+ router IP for load balancing and NAT purposes.
</p>
<p>
<p>
Protocol unreachable. Priority-70 flows generate ICMP protocol
unreachable messages in reply to packets directed to the router's IP
- address on IP protocols other than UDP, TCP, and ICMP.
+ address on IP protocols other than UDP, TCP, and ICMP, except in the
+ special case of gateways, which accept traffic directed to a router
+ IP for load balancing purposes.
</p>
<p>
ds_cstr(&match), ds_cstr(&actions));
}
- /* UDP/TCP port unreachable */
- for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) {
- const char *action;
-
- ds_clear(&match);
- ds_put_format(&match,
- "ip4 && ip4.dst == %s && !ip.later_frag && udp",
- op->lrp_networks.ipv4_addrs[i].addr_s);
- action = "icmp4 {"
- "eth.dst <-> eth.src; "
- "ip4.dst <-> ip4.src; "
- "ip.ttl = 255; "
- "icmp4.type = 3; "
- "icmp4.code = 3; "
- "next; };";
- ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
- ds_cstr(&match), action);
+ if (!smap_get(&op->od->nbr->options, "chassis")
+ && !op->od->l3dgw_port) {
+ /* UDP/TCP port unreachable. */
+ for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) {
+ ds_clear(&match);
+ ds_put_format(&match,
+ "ip4 && ip4.dst == %s && !ip.later_frag && udp",
+ op->lrp_networks.ipv4_addrs[i].addr_s);
+ const char *action = "icmp4 {"
+ "eth.dst <-> eth.src; "
+ "ip4.dst <-> ip4.src; "
+ "ip.ttl = 255; "
+ "icmp4.type = 3; "
+ "icmp4.code = 3; "
+ "next; };";
+ ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
+ ds_cstr(&match), action);
- ds_clear(&match);
- ds_put_format(&match,
- "ip4 && ip4.dst == %s && !ip.later_frag && tcp",
- op->lrp_networks.ipv4_addrs[i].addr_s);
- action = "tcp_reset {"
- "eth.dst <-> eth.src; "
- "ip4.dst <-> ip4.src; "
- "next; };";
- ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
- ds_cstr(&match), action);
+ ds_clear(&match);
+ ds_put_format(&match,
+ "ip4 && ip4.dst == %s && !ip.later_frag && tcp",
+ op->lrp_networks.ipv4_addrs[i].addr_s);
+ action = "tcp_reset {"
+ "eth.dst <-> eth.src; "
+ "ip4.dst <-> ip4.src; "
+ "next; };";
+ ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
+ ds_cstr(&match), action);
- ds_clear(&match);
- ds_put_format(&match,
- "ip4 && ip4.dst == %s && !ip.later_frag",
- op->lrp_networks.ipv4_addrs[i].addr_s);
- action = "icmp4 {"
- "eth.dst <-> eth.src; "
- "ip4.dst <-> ip4.src; "
- "ip.ttl = 255; "
- "icmp4.type = 3; "
- "icmp4.code = 2; "
- "next; };";
- ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 70,
- ds_cstr(&match), action);
+ ds_clear(&match);
+ ds_put_format(&match,
+ "ip4 && ip4.dst == %s && !ip.later_frag",
+ op->lrp_networks.ipv4_addrs[i].addr_s);
+ action = "icmp4 {"
+ "eth.dst <-> eth.src; "
+ "ip4.dst <-> ip4.src; "
+ "ip.ttl = 255; "
+ "icmp4.type = 3; "
+ "icmp4.code = 2; "
+ "next; };";
+ ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 70,
+ ds_cstr(&match), action);
+ }
}
ds_clear(&match);
}
/* TCP port unreachable */
- for (int i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) {
- const char *action;
-
- ds_clear(&match);
- ds_put_format(&match,
- "ip6 && ip6.dst == %s && !ip.later_frag && tcp",
- op->lrp_networks.ipv6_addrs[i].addr_s);
- action = "tcp_reset {"
- "eth.dst <-> eth.src; "
- "ip6.dst <-> ip6.src; "
- "next; };";
- ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
+ if (!smap_get(&op->od->nbr->options, "chassis")
+ && !op->od->l3dgw_port) {
+ for (int i = 0; i < op->lrp_networks.n_ipv6_addrs; i++) {
+ ds_clear(&match);
+ ds_put_format(&match,
+ "ip6 && ip6.dst == %s && !ip.later_frag && tcp",
+ op->lrp_networks.ipv6_addrs[i].addr_s);
+ const char *action = "tcp_reset {"
+ "eth.dst <-> eth.src; "
+ "ip6.dst <-> ip6.src; "
+ "next; };";
+ ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 80,
ds_cstr(&match), action);
+ }
}
}