When transit traffic arrives on an l3dgw port with TTL=0 or TTL=1,
northd generates an ICMP Time Exceeded reply. Previously, the action
for l3dgw ports used "ip4.dst <-> ip4.src", which swaps the source
and destination addresses. This sets the ICMP reply source to the
original packet's destination, instead of the receiving router port
address. For example, a packet from 203.0.113.50 destined to
10.0.0.5 would produce an ICMP error with source 10.0.0.5 instead
of the router port's own address.
Use "ip4.dst = ip4.src; ip4.src = <router_port_ip>" and
"eth.dst = eth.src; eth.src = %s" unconditionally
for both l3dgw and non-l3dgw ports, so the ICMP reply MAC and IP
address are always the router port's address in the matching subnet.
Fixes: 4ecc61247d86 ("northd: fix ttl exceeded with FIP")
Reported-at: https://redhat.atlassian.net/browse/FDP-4078
Signed-off-by: Mairtin O'Loingsigh <[email protected]>
---
v2 -> v3:
- Rebase on main.
v1 -> v2:
- Set source MAC to router port MAC.
NEWS | 2 +
northd/northd.c | 68 ++++++++++++-------------
tests/ovn-northd.at | 119 ++++++++++++++++++++++++++++++++++----------
3 files changed, 128 insertions(+), 61 deletions(-)
diff --git a/NEWS b/NEWS
index d1a6ad27f..797e289d3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,7 @@
Post v26.03.0
-------------
+ - Fixed support for TTL expired. Use router port IP and MAC instead of dest
+ IP and MAC for ICMP Time exceeded response.
- Load balancer health checks now "fail closed" for newly added backends:
ovn-northd initializes a newly created Service_Monitor row to the
"offline" state, so traffic is not forwarded to a backend until its first
diff --git a/northd/northd.c b/northd/northd.c
index e4cd93969..16356c6ca 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -16947,19 +16947,9 @@ build_lrouter_ipv4_default_ttl_expired_flows(
return;
}
- struct ds ip_ds = DS_EMPTY_INITIALIZER;
for (int i = 0; i < op->lrp_networks.n_ipv4_addrs; i++) {
ds_clear(match);
ds_clear(actions);
- ds_clear(&ip_ds);
- if (lrp_is_l3dgw(op)) {
- ds_put_cstr(&ip_ds, "ip4.dst <-> ip4.src");
- ds_put_format(match, "is_chassis_resident(%s) && ",
- op->cr_port->json_key);
- } else {
- 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 && "
"ip4.src == %s/%d && "
@@ -16967,23 +16957,28 @@ build_lrouter_ipv4_default_ttl_expired_flows(
op->json_key,
op->lrp_networks.ipv4_addrs[i].network_s,
op->lrp_networks.ipv4_addrs[i].plen);
+ if (lrp_is_l3dgw(op)) {
+ ds_put_format(match, " && is_chassis_resident(%s)",
+ op->cr_port->json_key);
+ }
+
ds_put_format(actions,
"icmp4 {"
- "eth.dst <-> eth.src; "
+ "eth.dst = eth.src; eth.src = %s; "
"icmp4.type = 11; /* Time exceeded */ "
"icmp4.code = 0; /* TTL exceeded in transit */ "
- "%s ; ip.ttl = 254; "
+ "ip4.dst = ip4.src; ip4.src = %s; ip.ttl = 254; "
"outport = %s; flags.loopback = 1; output; };",
- ds_cstr(&ip_ds), op->json_key);
+ op->lrp_networks.ea_s,
+ op->lrp_networks.ipv4_addrs[i].addr_s, op->json_key);
+
ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 31,
ds_cstr(match), ds_cstr(actions), lflow_ref,
WITH_CTRL_METER(copp_meter_get(COPP_ICMP4_ERR,
op->od->nbr->copp,
meter_groups)),
WITH_HINT(&op->nbrp->header_));
-
}
- ds_destroy(&ip_ds);
ds_clear(match);
ds_clear(actions);
@@ -16994,15 +16989,19 @@ build_lrouter_ipv4_default_ttl_expired_flows(
"inport == %s && ip4 && "
"ip.ttl == {0, 1} && !ip.later_frag",
op->json_key);
+ if (lrp_is_l3dgw(op)) {
+ ds_put_format(match, " && is_chassis_resident(%s)",
+ op->cr_port->json_key);
+ }
ds_put_format(actions,
"icmp4 {"
- "eth.dst <-> eth.src; "
+ "eth.dst = eth.src; eth.src = %s; "
"icmp4.type = 11; /* Time exceeded */ "
"icmp4.code = 0; /* TTL exceeded in transit */ "
"ip4.dst = ip4.src; ip4.src = %s; ip.ttl = 254; "
- "outport = %s; flags.loopback = 1; output; };",
- op->lrp_networks.ipv4_addrs[0].addr_s,
- op->json_key);
+ "outport = %s; flags.loopback = 1; output; };",
+ op->lrp_networks.ea_s, op->lrp_networks.ipv4_addrs[0].addr_s,
+ op->json_key);
ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 30,
ds_cstr(match), ds_cstr(actions), lflow_ref,
WITH_CTRL_METER(copp_meter_get(COPP_ICMP4_ERR,
@@ -17025,19 +17024,9 @@ build_lrouter_ipv6_default_ttl_expired_flows(
return;
}
- struct ds ip_ds = DS_EMPTY_INITIALIZER;
for (size_t i = 0; i < op->lrp_networks.n_ipv6_addrs - 1; i++) {
ds_clear(match);
ds_clear(actions);
- ds_clear(&ip_ds);
- if (lrp_is_l3dgw(op)) {
- ds_put_cstr(&ip_ds, "ip6.dst <-> ip6.src");
- ds_put_format(match, "is_chassis_resident(%s) && ",
- op->cr_port->json_key);
- } else {
- ds_put_format(&ip_ds, "ip6.dst = ip6.src; ip6.src = %s",
- op->lrp_networks.ipv6_addrs[i].addr_s);
- }
ds_put_format(match,
"inport == %s && ip6 && "
"ip6.src == %s/%d && "
@@ -17045,14 +17034,20 @@ build_lrouter_ipv6_default_ttl_expired_flows(
op->json_key,
op->lrp_networks.ipv6_addrs[i].network_s,
op->lrp_networks.ipv6_addrs[i].plen);
+ if (lrp_is_l3dgw(op)) {
+ ds_put_format(match, " && is_chassis_resident(%s)",
+ op->cr_port->json_key);
+ }
ds_put_format(actions,
"icmp6 {"
- "eth.dst <-> eth.src; "
- "%s ; ip.ttl = 254; "
+ "eth.dst = eth.src; eth.src = %s; "
+ "ip6.dst = ip6.src; ip6.src = %s; ip.ttl = 254; "
"icmp6.type = 3; /* Time exceeded */ "
"icmp6.code = 0; /* TTL exceeded in transit */ "
"outport = %s; flags.loopback = 1; output; };",
- ds_cstr(&ip_ds), op->json_key);
+ op->lrp_networks.ea_s,
+ op->lrp_networks.ipv6_addrs[i].addr_s, op->json_key);
+
ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 31,
ds_cstr(match), ds_cstr(actions), lflow_ref,
WITH_CTRL_METER(copp_meter_get(COPP_ICMP6_ERR,
@@ -17060,7 +17055,6 @@ build_lrouter_ipv6_default_ttl_expired_flows(
meter_groups)),
WITH_HINT(&op->nbrp->header_));
}
- ds_destroy(&ip_ds);
ds_clear(match);
ds_clear(actions);
@@ -17071,14 +17065,18 @@ build_lrouter_ipv6_default_ttl_expired_flows(
"inport == %s && ip6 && "
"ip.ttl == {0, 1} && !ip.later_frag",
op->json_key);
+ if (lrp_is_l3dgw(op)) {
+ ds_put_format(match, " && is_chassis_resident(%s)",
+ op->cr_port->json_key);
+ }
ds_put_format(actions,
"icmp6 {"
- "eth.dst <-> eth.src; "
+ "eth.dst = eth.src; eth.src = %s; "
"ip6.dst = ip6.src; ip6.src = %s; "
"ip.ttl = 254; icmp6.type = 3; /* Time exceeded */ "
"icmp6.code = 0; /* TTL exceeded in transit */ "
"outport = %s; flags.loopback = 1; output; };",
- op->lrp_networks.ipv6_addrs[0].addr_s,
+ op->lrp_networks.ea_s, op->lrp_networks.ipv6_addrs[0].addr_s,
op->json_key);
ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_INPUT, 30,
ds_cstr(match), ds_cstr(actions), lflow_ref,
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 2edcfc2cb..45e648e49 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -8608,14 +8608,14 @@ AT_CHECK([grep -e 'lr_in_ip_input ' lrflows | grep
-e 'igmp' -e 'mld' -e 'ip.
table=??(lr_in_ip_input ), priority=120 , match=((mldv1 || mldv2) &&
ip.ttl == 1), action=(next;)
table=??(lr_in_ip_input ), priority=120 , match=(igmp && ip.ttl == 1),
action=(next;)
table=??(lr_in_ip_input ), priority=29 , match=(ip.ttl == {0, 1}),
action=(drop;)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 10.10.10.1; ip.ttl = 254; outport = "lrp1";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = 1010::1; ip.ttl = 254; icmp6.type = 3; /* Time
exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport = "lrp1";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp2" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 20.20.20.1; ip.ttl = 254; outport = "lrp2";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp2" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = 2020::1; ip.ttl = 254; icmp6.type = 3; /* Time
exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport = "lrp2";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp1" &&
ip4 && ip4.src == 10.10.10.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
10.10.10.1 ; ip.ttl = 254; outport = "lrp1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp1" &&
ip6 && ip6.src == 1010::/64 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp6 {eth.dst <-> eth.src; ip6.dst = ip6.src; ip6.src = 1010::1 ;
ip.ttl = 254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL
exceeded in transit */ outport = "lrp1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp2" &&
ip4 && ip4.src == 20.20.20.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
20.20.20.1 ; ip.ttl = 254; outport = "lrp2"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp2" &&
ip6 && ip6.src == 2020::/64 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp6 {eth.dst <-> eth.src; ip6.dst = ip6.src; ip6.src = 2020::1 ;
ip.ttl = 254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL
exceeded in transit */ outport = "lrp2"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:00:01; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.10.10.1;
ip.ttl = 254; outport = "lrp1"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:00:01; ip6.dst = ip6.src; ip6.src = 1010::1; ip.ttl =
254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in
transit */ outport = "lrp1"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp2" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:00:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 20.20.20.1;
ip.ttl = 254; outport = "lrp2"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lrp2" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:00:02; ip6.dst = ip6.src; ip6.src = 2020::1; ip.ttl =
254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in
transit */ outport = "lrp2"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp1" &&
ip4 && ip4.src == 10.10.10.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:00:01; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 10.10.10.1; ip.ttl = 254; outport = "lrp1"; flags.loopback =
1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp1" &&
ip6 && ip6.src == 1010::/64 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp6 {eth.dst = eth.src; eth.src = 00:00:00:00:00:01; ip6.dst =
ip6.src; ip6.src = 1010::1; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lrp1"; flags.loopback
= 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp2" &&
ip4 && ip4.src == 20.20.20.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:00:02; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 20.20.20.1; ip.ttl = 254; outport = "lrp2"; flags.loopback =
1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lrp2" &&
ip6 && ip6.src == 2020::/64 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp6 {eth.dst = eth.src; eth.src = 00:00:00:00:00:02; ip6.dst =
ip6.src; ip6.src = 2020::1; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lrp2"; flags.loopback
= 1; output; };)
table=??(lr_in_ip_input ), priority=32 , match=(ip.ttl == {0, 1} &&
!ip.later_frag && (ip4.mcast || ip6.mcast)), action=(drop;)
])
@@ -8635,6 +8635,73 @@ OVN_CLEANUP_NORTHD
AT_CLEANUP
])
+OVN_FOR_EACH_NORTHD_NO_HV([
+AT_SETUP([TTL exceeded -- l3dgw port uses correct source IP])
+AT_KEYWORDS([ttl-exceeded l3dgw])
+ovn_start
+
+check ovn-nbctl lr-add lr0
+check ovn-nbctl ls-add sw0
+check ovn-nbctl ls-add public
+
+check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:ff:01 10.0.0.1/24
2001:db8::1/64
+check ovn-nbctl lsp-add-router-port sw0 sw0-lr0 lr0-sw0
+
+check ovn-nbctl lrp-add lr0 lr0-public 00:00:00:00:ff:02 172.168.0.10/24
2001:db8:1::1/64
+check ovn-nbctl lsp-add-router-port public public-lr0 lr0-public
+
+check ovn-sbctl chassis-add gw1 geneve 127.0.0.1
+check ovn-nbctl lrp-set-gateway-chassis lr0-public gw1
+
+check ovn-nbctl --wait=sb sync
+
+ovn-sbctl dump-flows lr0 > lr0flows
+AT_CAPTURE_FILE([lr0flows])
+
+dnl The priority-31 TTL expired flow for the l3dgw port must use explicit
+dnl ip4.src assignment (the router port IP), not ip4.dst <-> ip4.src swap.
+AT_CHECK([grep 'priority=31.*lr0-public.*ip4.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-public"
&& ip4 && ip4.src == 172.168.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+])
+
+dnl Non-l3dgw port should also use explicit assignment (unchanged behavior).
+AT_CHECK([grep 'priority=31.*lr0-sw0.*ip4.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip4 && ip4.src == 10.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:01; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 10.0.0.1; ip.ttl = 254; outport = "lr0-sw0"; flags.loopback
= 1; output; };)
+])
+
+dnl IPv6: l3dgw port must use explicit ip6.src assignment, not swap.
+AT_CHECK([grep 'priority=31.*lr0-public.*ip6.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-public"
&& ip6 && ip6.src == 2001:db8:1::/64 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = 2001:db8:1::1; ip.ttl
= 254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in
transit */ outport = "lr0-public"; flags.loopback = 1; output; };)
+])
+
+dnl IPv6: non-l3dgw port (unchanged behavior).
+AT_CHECK([grep 'priority=31.*lr0-sw0.*ip6.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip6 && ip6.src == 2001:db8::/64 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp6 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:01; ip6.dst =
ip6.src; ip6.src = 2001:db8::1; ip.ttl = 254; icmp6.type = 3; /* Time exceeded
*/ icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-sw0";
flags.loopback = 1; output; };)
+])
+
+AT_CHECK([grep 'priority=30.*lr0-public.*ip4.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip4 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+])
+
+dnl Non-l3dgw port should also use explicit assignment (unchanged behavior).
+AT_CHECK([grep 'priority=30.*lr0-sw0.*ip4.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl
= 254; outport = "lr0-sw0"; flags.loopback = 1; output; };)
+])
+
+dnl IPv6: l3dgw port must use explicit ip6.src assignment, not swap.
+AT_CHECK([grep 'priority=30.*lr0-public.*ip6.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip6 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = 2001:db8:1::1; ip.ttl
= 254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in
transit */ outport = "lr0-public"; flags.loopback = 1; output; };)
+])
+
+dnl IPv6: non-l3dgw port (unchanged behavior).
+AT_CHECK([grep 'priority=30.*lr0-sw0.*ip6.*ip.ttl' lr0flows |
ovn_strip_lflows], [0], [dnl
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = 2001:db8::1; ip.ttl =
254; icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in
transit */ outport = "lr0-sw0"; flags.loopback = 1; output; };)
+])
+
+OVN_CLEANUP_NORTHD
+AT_CLEANUP
+])
+
OVN_FOR_EACH_NORTHD_NO_HV([
AT_SETUP([IP multicast flood without IGMP relay])
AT_KEYWORDS([mcast_relay])
@@ -14634,15 +14701,15 @@ AT_CHECK([grep "lr_in_ip_input" lr0flows |
ovn_strip_lflows], [0], [dnl
table=??(lr_in_ip_input ), priority=100 , match=(ip4.src_mcast
||ip4.src == 255.255.255.255 || ip4.src == 127.0.0.0/8 || ip4.dst ==
127.0.0.0/8 || ip4.src == 0.0.0.0/8 || ip4.dst == 0.0.0.0/8), action=(drop;)
table=??(lr_in_ip_input ), priority=120 , match=(inport == "lr0-public"
&& ip4.src == 172.168.0.100), action=(next;)
table=??(lr_in_ip_input ), priority=29 , match=(ip.ttl == {0, 1}),
action=(drop;)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <->
eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded
in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10; ip.ttl = 254; outport
= "lr0-public"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <->
eth.src; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 254;
icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit
*/ outport = "lr0-public"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 254; outport = "lr0-sw0";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 254; icmp6.type =
3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport =
"lr0-sw0"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 254; outport = "lr0-sw1";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff03; ip.ttl = 254; icmp6.type =
3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport =
"lr0-sw1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip4 && ip4.src == 10.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
10.0.0.1 ; ip.ttl = 254; outport = "lr0-sw0"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw1" &&
ip4 && ip4.src == 20.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
20.0.0.1 ; ip.ttl = 254; outport = "lr0-sw1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 ,
match=(is_chassis_resident("cr-lr0-public") && inport == "lr0-public" && ip4 &&
ip4.src == 172.168.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4
{eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /*
TTL exceeded in transit */ ip4.dst <-> ip4.src ; ip.ttl = 254; outport =
"lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip4 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip6 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff02; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-public";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl
= 254; outport = "lr0-sw0"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff01; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-sw0";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:03; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl
= 254; outport = "lr0-sw1"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:03; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff03; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-sw1";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-public"
&& ip4 && ip4.src == 172.168.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip4 && ip4.src == 10.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:01; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 10.0.0.1; ip.ttl = 254; outport = "lr0-sw0"; flags.loopback
= 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw1" &&
ip4 && ip4.src == 20.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:03; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 20.0.0.1; ip.ttl = 254; outport = "lr0-sw1"; flags.loopback
= 1; output; };)
table=??(lr_in_ip_input ), priority=32 , match=(ip.ttl == {0, 1} &&
!ip.later_frag && (ip4.mcast || ip6.mcast)), action=(drop;)
table=??(lr_in_ip_input ), priority=50 , match=(eth.bcast),
action=(drop;)
table=??(lr_in_ip_input ), priority=60 , match=(ip4.dst ==
{10.0.0.1}), action=(drop;)
@@ -14816,15 +14883,15 @@ AT_CHECK([grep "lr_in_ip_input" lr0flows |
ovn_strip_lflows], [0], [dnl
table=??(lr_in_ip_input ), priority=100 , match=(ip4.src_mcast
||ip4.src == 255.255.255.255 || ip4.src == 127.0.0.0/8 || ip4.dst ==
127.0.0.0/8 || ip4.src == 0.0.0.0/8 || ip4.dst == 0.0.0.0/8), action=(drop;)
table=??(lr_in_ip_input ), priority=120 , match=(inport == "lr0-public"
&& ip4.src == 172.168.0.100), action=(next;)
table=??(lr_in_ip_input ), priority=29 , match=(ip.ttl == {0, 1}),
action=(drop;)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <->
eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded
in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10; ip.ttl = 254; outport
= "lr0-public"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <->
eth.src; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 254;
icmp6.type = 3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit
*/ outport = "lr0-public"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 254; outport = "lr0-sw0";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 254; icmp6.type =
3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport =
"lr0-sw0"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst <-> eth.src;
icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit
*/ ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl = 254; outport = "lr0-sw1";
flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst <-> eth.src;
ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff03; ip.ttl = 254; icmp6.type =
3; /* Time exceeded */ icmp6.code = 0; /* TTL exceeded in transit */ outport =
"lr0-sw1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip4 && ip4.src == 10.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
10.0.0.1 ; ip.ttl = 254; outport = "lr0-sw0"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw1" &&
ip4 && ip4.src == 20.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */
icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src =
20.0.0.1 ; ip.ttl = 254; outport = "lr0-sw1"; flags.loopback = 1; output; };)
- table=??(lr_in_ip_input ), priority=31 ,
match=(is_chassis_resident("cr-lr0-public") && inport == "lr0-public" && ip4 &&
ip4.src == 172.168.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4
{eth.dst <-> eth.src; icmp4.type = 11; /* Time exceeded */ icmp4.code = 0; /*
TTL exceeded in transit */ ip4.dst <-> ip4.src ; ip.ttl = 254; outport =
"lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip4 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-public"
&& ip6 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff02; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-public";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl
= 254; outport = "lr0-sw0"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw0" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff01; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-sw0";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip4 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:03; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 20.0.0.1; ip.ttl
= 254; outport = "lr0-sw1"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=30 , match=(inport == "lr0-sw1" &&
ip6 && ip.ttl == {0, 1} && !ip.later_frag), action=(icmp6 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:03; ip6.dst = ip6.src; ip6.src =
fe80::200:ff:fe00:ff03; ip.ttl = 254; icmp6.type = 3; /* Time exceeded */
icmp6.code = 0; /* TTL exceeded in transit */ outport = "lr0-sw1";
flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-public"
&& ip4 && ip4.src == 172.168.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag &&
is_chassis_resident("cr-lr0-public")), action=(icmp4 {eth.dst = eth.src;
eth.src = 00:00:00:00:ff:02; icmp4.type = 11; /* Time exceeded */ icmp4.code =
0; /* TTL exceeded in transit */ ip4.dst = ip4.src; ip4.src = 172.168.0.10;
ip.ttl = 254; outport = "lr0-public"; flags.loopback = 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw0" &&
ip4 && ip4.src == 10.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:01; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 10.0.0.1; ip.ttl = 254; outport = "lr0-sw0"; flags.loopback
= 1; output; };)
+ table=??(lr_in_ip_input ), priority=31 , match=(inport == "lr0-sw1" &&
ip4 && ip4.src == 20.0.0.0/24 && ip.ttl == {0, 1} && !ip.later_frag),
action=(icmp4 {eth.dst = eth.src; eth.src = 00:00:00:00:ff:03; icmp4.type = 11;
/* Time exceeded */ icmp4.code = 0; /* TTL exceeded in transit */ ip4.dst =
ip4.src; ip4.src = 20.0.0.1; ip.ttl = 254; outport = "lr0-sw1"; flags.loopback
= 1; output; };)
table=??(lr_in_ip_input ), priority=32 , match=(ip.ttl == {0, 1} &&
!ip.later_frag && (ip4.mcast || ip6.mcast)), action=(drop;)
table=??(lr_in_ip_input ), priority=50 , match=(eth.bcast),
action=(drop;)
table=??(lr_in_ip_input ), priority=60 , match=(ip4.dst ==
{10.0.0.1}), action=(drop;)
--
2.54.0
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev