Skip to content

Commit

Permalink
Allow LR to send RAs through localnet port.
Browse files Browse the repository at this point in the history
Modifies the rule responsible for dropping the MLF_LOCAL_ONLY packets
to only drop them if the MLF_OVERRIDE_LOCAL_ONLY bit flag is not there.

This does also include the addition of MLF_OVERRIDE_LOCAL_ONLY bitflag applied
if a router announcement is being sent from either a gateway
or distributed router.

This is part of an ongoing unnumbered BGP effort.
Backport specific patch for v24.03

Signed-off-by: MJ Ponsonby <mj.ponsonby@canonical.com>
Signed-off-by: Dumitru Ceara <dceara@redhat.com>
(cherry picked from commit 744340f)
  • Loading branch information
crypticC0der authored and dceara committed Jan 20, 2025
1 parent b48f7ea commit bf1a222
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 5 deletions.
3 changes: 2 additions & 1 deletion controller/physical.c
Original file line number Diff line number Diff line change
Expand Up @@ -1869,7 +1869,8 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
put_drop(debug, OFTABLE_CHECK_LOOPBACK, ofpacts_p);
match_outport_dp_and_port_keys(&match, dp_key, port_key);
match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
MLF_LOCAL_ONLY, MLF_LOCAL_ONLY);
MLF_LOCAL_ONLY,
MLF_LOCAL_ONLY | MLF_OVERRIDE_LOCAL_ONLY);
ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 160,
binding->header_.uuid.parts[0], &match,
ofpacts_p, &binding->header_.uuid);
Expand Down
11 changes: 9 additions & 2 deletions controller/pinctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4108,6 +4108,7 @@ struct ipv6_ra_state {
struct ipv6_ra_config *config;
int64_t port_key;
int64_t metadata;
bool preserved;
bool delete_me;
};

Expand Down Expand Up @@ -4433,6 +4434,9 @@ ipv6_ra_send(struct rconn *swconn, struct ipv6_ra_state *ra)
put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
if (ra->preserved) {
put_load(1, MFF_LOG_FLAGS, MLF_OVERRIDE_LOCAL_ONLY_BIT, 1, &ofpacts);
}
struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
resubmit->in_port = OFPP_CONTROLLER;
resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
Expand Down Expand Up @@ -4543,8 +4547,11 @@ prepare_ipv6_ras(const struct shash *local_active_ports_ras,
* router port is connected to. The RA is injected
* into that logical switch port.
*/
ra->port_key = peer->tunnel_key;
ra->metadata = peer->datapath->tunnel_key;
ra->port_key = peer->tunnel_key;
ra->metadata = peer->datapath->tunnel_key;
ra->preserved = (!strcmp(pb->type,"l2gateway") ||
!strcmp(pb->type,"l3gateway") ||
!strcmp(pb->type,"chassisredirect"));
ra->delete_me = false;

/* pinctrl_handler thread will send the IPv6 RAs. */
Expand Down
3 changes: 3 additions & 0 deletions include/ovn/logical-fields.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ enum mff_log_flags_bits {
MLF_LOCALNET_BIT = 15,
MLF_RX_FROM_TUNNEL_BIT = 16,
MLF_ICMP_SNAT_BIT = 17,
MLF_OVERRIDE_LOCAL_ONLY_BIT = 18,
};

/* MFF_LOG_FLAGS_REG flag assignments */
Expand Down Expand Up @@ -142,6 +143,8 @@ enum mff_log_flags {
MLF_RX_FROM_TUNNEL = (1 << MLF_RX_FROM_TUNNEL_BIT),

MLF_ICMP_SNAT = (1 << MLF_ICMP_SNAT_BIT),

MLF_OVERRIDE_LOCAL_ONLY = (1 << MLF_OVERRIDE_LOCAL_ONLY_BIT),
};

/* OVN logical fields
Expand Down
6 changes: 4 additions & 2 deletions ovn-architecture.7.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1546,8 +1546,10 @@
<p>
Table 41 matches and drops packets for which the logical input and
output ports are the same and the MLF_ALLOW_LOOPBACK flag is not
set. It also drops MLF_LOCAL_ONLY packets directed to a localnet port.
It resubmits other packets to table 42.
set. It also drops MLF_LOCAL_ONLY packets directed to a localnet port,
provided they aren't RAs sent from a gateway or distributed router
which is checked via the presence of the bitflag
MLF_OVERRIDE_LOCAL_ONLY. It resubmits other packets to table 42.
</p>
</li>

Expand Down
105 changes: 105 additions & 0 deletions tests/ovn.at
Original file line number Diff line number Diff line change
Expand Up @@ -17088,6 +17088,111 @@ OVN_CLEANUP([hv1],[hv2])
AT_CLEANUP
])


OVN_FOR_EACH_NORTHD([
AT_SETUP([IPv6 periodic gateway RA enabled for localnet adjacent switch ports])
ovn_start

net_add n1
sim_add hv1
sim_add hv2
as hv1
check ovs-vsctl add-br br-phys
check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
ovn_attach n1 br-phys 192.168.0.2
as hv2
check ovs-vsctl add-br br-phys
check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys
ovn_attach n1 br-phys 192.168.0.3

check ovn-nbctl lr-add ro -- set Logical_Router ro options:chassis="hv1"
check ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 20.0.0.1/24

check ovn-nbctl ls-add sw
check ovn-nbctl lsp-add sw ln
check ovn-nbctl lsp-set-addresses ln unknown
check ovn-nbctl lsp-set-type ln localnet
check ovn-nbctl lsp-set-options ln network_name=phys

check ovn-nbctl lsp-add sw sw-ro
check ovn-nbctl lsp-set-type sw-ro router
check ovn-nbctl lsp-set-options sw-ro router-port=ro-sw
check ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01
check ovn-nbctl lsp-add sw sw-p1
check ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2"
check ovn-nbctl lsp-add sw sw-p2
check ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3"

AT_CHECK([ovn-sbctl get Port_Binding ro-sw type | tr -d '\n'],[0],[l3gateway])

check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true
check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac
check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=1
check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=1

for i in 1 2 ; do
as hv$i
check ovs-vsctl -- add-port br-int hv$i-vif1 -- \
set interface hv$i-vif1 external-ids:iface-id=sw-p$i \
options:tx_pcap=hv$i/vif1-tx.pcap \
options:rxq_pcap=hv$i/vif1-rx.pcap \
ofport-request=1
done

wait_for_ports_up
check ovn-nbctl --wait=hv sync

ra_received() {
$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $1 | sed '/^ffffffffffff/d' | wc -l
}

ra_test() {
interface=$1
shift 1
local ra_packet=$(fmt_pkt "
Ether(src='00:00:00:00:00:01', dst='33:33:00:00:00:01') /
IPv6(dst='ff02::1', src='fe80::200:ff:fe00:1') /
ICMPv6ND_RA(chlim=255, prf=0, routerlifetime=65535) /
ICMPv6NDOptSrcLLAddr(lladdr='00:00:00:00:00:01')
")
intname="$interface"

for i in hv1 hv2 ; do
if echo "$interface" | grep -q -v "br"; then
intname="$i-$interface"
fi
echo $intname
as $i reset_pcap_file $intname $i/$interface

OVS_WAIT_WHILE([test 0 = $(ra_received $i/$interface-tx.pcap)])

$PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $i/$interface-tx.pcap > packets
sed -i '/^ffffffffffff/d' packets

echo ${ra_packet} | cut -c -112 > expout
AT_CHECK([head -1 packets | cut -c -112], [0], [expout])

# Skip ICMPv6 checksum.
echo ${ra_packet} | cut -c 117- > expout
AT_CHECK([head -1 packets | cut -c 117-], [0], [expout])

rm -f packets
as $i reset_pcap_file $intname $i/$interface
done

rm -f expected
}

# check that RAs are sent
ra_test vif1

# check that RAs are recived on br-phys
ra_test br-phys

OVN_CLEANUP([hv1],[hv2])
AT_CLEANUP
])

OVN_FOR_EACH_NORTHD([
AT_SETUP([ACL reject rule test])
AT_KEYWORDS([acl-reject])
Expand Down

0 comments on commit bf1a222

Please sign in to comment.