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_KEEP_RA bit flag is not there.

This does also include the addition of MLF_KEEP_RA 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.

Signed-off-by: MJ Ponsonby <mj.ponsonby@canonical.com>
Signed-off-by: 0-day Robot <robot@bytheb.org>
  • Loading branch information
crypticC0der authored and ovsrobot committed Jan 6, 2025
1 parent dbdd8ea commit 0f80eee
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 4 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_KEEP_RA);
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 @@ -4107,6 +4107,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 @@ -4432,6 +4433,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_KEEP_RA_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 @@ -4542,8 +4546,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_KEEP_RA_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_KEEP_RA = (1 << MLF_KEEP_RA_BIT),
};

/* OVN logical fields
Expand Down
4 changes: 3 additions & 1 deletion ovn-architecture.7.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1546,7 +1546,9 @@
<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.
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_KEEP_RA.
It resubmits other packets to table 42.
</p>
</li>
Expand Down
152 changes: 152 additions & 0 deletions tests/ovn.at
Original file line number Diff line number Diff line change
Expand Up @@ -16935,6 +16935,158 @@ 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

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

construct_expected_ra() {
local src_mac=000000000001
local dst_mac=333300000001
local src_addr=fe80000000000000020000fffe000001
local dst_addr=ff020000000000000000000000000001

local mtu=$1
local ra_mo=$2
local rdnss=$3
local dnssl=$4
local route_info=$5
local ra_prefix_la=$6

local slla=0101${src_mac}
local mtu_opt=""
if test $mtu != 0; then
mtu_opt=05010000${mtu}
fi
shift 6

local prefix=""
while [[ $# -gt 0 ]] ; do
local size=$1
local net=$2
prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net}
shift 2
done

local rdnss_opt=""
if test $rdnss != 0; then
rdnss_opt=19030000ffffffff${rdnss}
fi
local dnssl_opt=""
if test $dnssl != 0; then
dnssl_opt=1f030000ffffffff${dnssl}
fi
local route_info_opt=""
if test $route_info != 0; then
route_info_opt=${route_info}
fi

local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}${rdnss_opt}${dnssl_opt}${route_info_opt}
local icmp=8600XXXX${ra}

local ip_len=$(expr ${#icmp} / 2)
ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}')

local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp}
local eth=${dst_mac}${src_mac}86dd${ip}
local packet=${eth}
echo $packet >> expected
}

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

ra_test() {
interface=$1
shift 1
construct_expected_ra $@
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

cat expected | cut -c -112 > expout
AT_CHECK([head -1 packets | cut -c -112], [0], [expout])

# Skip ICMPv6 checksum.
cat expected | 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 0 00 0 0 0 c0

# check that RAs are recived on br-phys
ra_test br-phys 0 00 0 0 0 c0

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 0f80eee

Please sign in to comment.