pax_global_header00006660000000000000000000000064150453266110014515gustar00rootroot0000000000000052 comment=23884f516a24dd58c5d96b3c35ced038ecdcb703 ovn-25.09.0~git20250813.23884f5/000077500000000000000000000000001504532661100151455ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.ci/000077500000000000000000000000001504532661100156165ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.ci/ci.sh000077500000000000000000000111671504532661100165560ustar00rootroot00000000000000#!/bin/bash -xe # Copyright (c) 2022, Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # OVN_PATH=${OVN_PATH:-$PWD} OVS_PATH=${OVS_PATH:-$OVN_PATH/ovs} CONTAINER_CMD=${CONTAINER_CMD:-podman} CONTAINER_WORKSPACE="/workspace" CONTAINER_WORKDIR="/workspace/ovn-tmp" IMAGE_NAME=${IMAGE_NAME:-"ovn-org/ovn-tests"} TIMEOUT=${TIMEOUT:-"0"} # Test variables ARCH=${ARCH:-$(uname -m)} CC=${CC:-gcc} test -t 1 && USE_TTY="t" function container_exec() { ${CONTAINER_CMD} exec "-i$USE_TTY" "$CONTAINER_ID" /bin/bash -c "$1" } function container_shell() { ${CONTAINER_CMD} exec "-i$USE_TTY" "$CONTAINER_ID" /bin/bash } function archive_logs() { if [ -z "$archive_logs" ]; then return 0; fi log_dir=$CONTAINER_WORKSPACE/logs/ container_exec " mkdir $log_dir \ && \ cp $CONTAINER_WORKDIR/config.log $log_dir \ && \ cp -r $CONTAINER_WORKDIR/tests/testsuite.* \ $log_dir || true \ && \ cp -r $CONTAINER_WORKDIR/tests/system-*-testsuite.* \ $log_dir || true \ && \ chmod -R +r $log_dir \ && tar -czvf $CONTAINER_WORKSPACE/logs.tgz $log_dir " ${CONTAINER_CMD} cp "$CONTAINER_ID:/$CONTAINER_WORKSPACE/logs.tgz" logs.tgz } function remove_container() { res=$? if [ "$res" -ne 0 ]; then archive_logs echo "*** ERROR: $res ***" fi ${CONTAINER_CMD} rm -f "$CONTAINER_ID" } function copy_sources_to_workdir() { container_exec " mkdir -p $CONTAINER_WORKDIR \ && \ cp -a $CONTAINER_WORKSPACE/ovn/. $CONTAINER_WORKDIR \ && \ rm -rf $CONTAINER_WORKDIR/ovs \ && \ cp -a $CONTAINER_WORKSPACE/ovs/. $CONTAINER_WORKDIR/ovs \ && \ rm -rf $CONTAINER_WORKDIR/dpdk-dir \ && \ cp -a $CONTAINER_WORKSPACE/dpdk-dir/. $CONTAINER_WORKDIR/dpdk-dir \ && \ git config --global --add safe.directory $CONTAINER_WORKDIR " } function overwrite_jobs() { container_exec " sed -i s/-j[0-9]/-j$jobs/ $CONTAINER_WORKDIR/.ci/linux-build.sh " } function run_tests() { container_exec " cd $CONTAINER_WORKDIR \ && \ ARCH=$ARCH CC=$CC LIBS=$LIBS OPTS=$OPTS TESTSUITE=$TESTSUITE \ TEST_RANGE=$TEST_RANGE SANITIZERS=$SANITIZERS DPDK=$DPDK \ RECHECK=$RECHECK UNSTABLE=$UNSTABLE TIMEOUT=$TIMEOUT \ ./.ci/linux-build.sh " } function check_clang_version_ge() { lower=$1 version=$(clang --version | head -n1 | cut -d' ' -f3) if ! echo -e "$lower\n$version" | sort -CV; then return 1 fi return 0 } options=$(getopt --options "" \ --long help,shell,archive-logs,jobs:,ovn-path:,ovs-path:,image-name:,timeout:\ -- "${@}") eval set -- "$options" while true; do case "$1" in --shell) shell="1" ;; --jobs) shift jobs="$1" ;; --ovn-path) shift OVN_PATH="$1" ;; --ovs-path) shift OVS_PATH="$1" ;; --image-name) shift IMAGE_NAME="$1" ;; --archive-logs) archive_logs="1" ;; --timeout) shift TIMEOUT="$1" ;; --help) set +x printf "$0 [--shell] [--help] [--archive-logs] [--jobs=] " printf "[--ovn-path=] [--ovs-path=] " printf "[--image-name=] [--timeout=]\n" exit ;; --) shift break ;; esac shift done # Workaround for https://bugzilla.redhat.com/2153359 if [ "$ARCH" = "aarch64" ] && ! check_clang_version_ge "16.0.0"; then ASAN_OPTIONS="detect_leaks=0" fi CONTAINER_ID="$($CONTAINER_CMD run --privileged -d \ --pids-limit=-1 \ --security-opt apparmor=unconfined \ --env ASAN_OPTIONS=$ASAN_OPTIONS \ -v /lib/modules/$(uname -r):/lib/modules/$(uname -r):ro \ -v $OVN_PATH:$CONTAINER_WORKSPACE/ovn:Z \ -v $OVS_PATH:$CONTAINER_WORKSPACE/ovs:Z \ $IMAGE_NAME)" trap remove_container EXIT copy_sources_to_workdir if [ -n "$jobs" ]; then overwrite_jobs fi if [ -n "$shell" ];then container_shell exit 0 fi run_tests ovn-25.09.0~git20250813.23884f5/.ci/linux-build.sh000077500000000000000000000143511504532661100204150ustar00rootroot00000000000000#!/bin/bash set -o errexit set -x ARCH=${ARCH:-"x86_64"} USE_SPARSE=${USE_SPARSE:-"yes"} COMMON_CFLAGS="" OVN_CFLAGS="" OPTS="$OPTS --enable-Werror" JOBS=${JOBS:-"-j4"} RECHECK=${RECHECK:-"no"} TIMEOUT=${TIMEOUT:-"0"} function install_dpdk() { local DPDK_INSTALL_DIR="$(pwd)/dpdk-dir" local VERSION_FILE="${DPDK_INSTALL_DIR}/cached-version" local DPDK_PC=$(find $DPDK_INSTALL_DIR -type f -name libdpdk-libs.pc) # Export the following path for pkg-config to find the .pc file. export PKG_CONFIG_PATH="$(dirname $DPDK_PC):$PKG_CONFIG_PATH" if [ ! -f "${VERSION_FILE}" ]; then echo "Could not find DPDK in $DPDK_INSTALL_DIR" return 1 fi # As we build inside a container we need to update the prefix. sed -i -E "s|^prefix=.*|prefix=${DPDK_INSTALL_DIR}|" $DPDK_PC # Update the library paths. sudo ldconfig echo "Found cached DPDK $(cat ${VERSION_FILE}) build in $DPDK_INSTALL_DIR" } function configure_ovs() { if [ "$DPDK" ]; then # When DPDK is enabled, we need to build OVS twice. Once to have # ovs-vswitchd with DPDK. But OVN does not like the OVS libraries to # be compiled with DPDK enabled, hence we need a final clean build # with this disabled. install_dpdk pushd ovs ./boot.sh && ./configure CFLAGS="${COMMON_CFLAGS}" --with-dpdk=static \ $* || { cat config.log; exit 1; } make $JOBS || { cat config.log; exit 1; } cp vswitchd/ovs-vswitchd vswitchd/ovs-vswitchd_with_dpdk popd fi pushd ovs ./boot.sh && ./configure CFLAGS="${COMMON_CFLAGS}" $* || \ { cat config.log; exit 1; } make $JOBS || { cat config.log; exit 1; } popd if [ "$DPDK" ]; then cp ovs/vswitchd/ovs-vswitchd_with_dpdk ovs/vswitchd/ovs-vswitchd fi } function configure_ovn() { configure_ovs $* ./boot.sh && ./configure CFLAGS="${COMMON_CFLAGS} ${OVN_CFLAGS}" $* || \ { cat config.log; exit 1; } } function configure_gcc() { if [ "$ARCH" = "x86_64" ] && [ "$USE_SPARSE" = "yes" ]; then # Enable sparse only for x86_64 architecture. OPTS="$OPTS --enable-sparse" elif [ "$ARCH" = "x86" ]; then # Adding m32 flag directly to CC to avoid any possible issues # with API/ABI difference on 'configure' and 'make' stages. export CC="$CC -m32" if which apt; then # We should install gcc-multilib for x86 build, we cannot # do it directly because gcc-multilib is not available # for arm64 sudo apt update && sudo apt install -y gcc-multilib elif which dnf; then # Install equivalent of gcc-multilib for Fedora. sudo dnf -y install glibc-devel.i686 fi fi } function configure_clang() { # If AddressSanitizer and UndefinedBehaviorSanitizer are requested, # enable them, but only for OVN, not for OVS. However, disable some # optimizations for OVS, to make sanitizer reports user friendly. if [ "$SANITIZERS" ]; then # Use the default options configured in tests/atlocal.in, # in UBSAN_OPTIONS. COMMON_CFLAGS="${COMMON_CFLAGS} -O1 -fno-omit-frame-pointer -fno-common -g" OVN_CFLAGS="${OVN_CFLAGS} -fsanitize=address,undefined" fi COMMON_CFLAGS="${COMMON_CFLAGS} -Wno-error=unused-command-line-argument" } function execute_dist_tests() { # 'distcheck' will reconfigure with required options. # Now we only need to prepare the Makefile without sparse-wrapped CC. configure_ovn export DISTCHECK_CONFIGURE_FLAGS="$OPTS" # Just list the tests during distcheck. if ! timeout -k 5m -v $TIMEOUT make distcheck \ CFLAGS="${COMMON_CFLAGS} ${OVN_CFLAGS}" $JOBS \ TESTSUITEFLAGS="-l" then # config.log is necessary for debugging. cat config.log exit 1 fi } function run_tests() { if ! timeout -k 5m -v $TIMEOUT make check \ CFLAGS="${COMMON_CFLAGS} ${OVN_CFLAGS}" $JOBS \ TESTSUITEFLAGS="$JOBS $TEST_RANGE" RECHECK=$RECHECK \ SKIP_UNSTABLE=$SKIP_UNSTABLE then # testsuite.log is necessary for debugging. cat tests/testsuite.log return 1 fi } function execute_tests() { configure_ovn $OPTS make $JOBS || { cat config.log; exit 1; } local stable_rc=0 local unstable_rc=0 if ! SKIP_UNSTABLE=yes run_tests; then stable_rc=1 fi if [ "$UNSTABLE" ]; then if ! SKIP_UNSTABLE=no TEST_RANGE="-k unstable" RECHECK=yes \ run_tests; then unstable_rc=1 fi fi if [[ $stable_rc -ne 0 ]] || [[ $unstable_rc -ne 0 ]]; then exit 1 fi } function run_system_tests() { local type=$1 local log_file=$2 if ! sudo timeout -k 5m -v $TIMEOUT make $JOBS $type \ TESTSUITEFLAGS="$TEST_RANGE" RECHECK=$RECHECK \ SKIP_UNSTABLE=$SKIP_UNSTABLE; then # $log_file is necessary for debugging. cat tests/$log_file return 1 fi } function execute_system_tests() { configure_ovn $OPTS make $JOBS || { cat config.log; exit 1; } local stable_rc=0 local unstable_rc=0 if ! SKIP_UNSTABLE=yes run_system_tests $@; then stable_rc=1 fi if [ "$UNSTABLE" ]; then if ! SKIP_UNSTABLE=no TEST_RANGE="-k unstable" RECHECK=yes \ run_system_tests $@; then unstable_rc=1 fi fi if [[ $stable_rc -ne 0 ]] || [[ $unstable_rc -ne 0 ]]; then exit 1 fi } configure_$CC if [ "$TESTSUITE" ]; then case "$TESTSUITE" in "test") execute_tests ;; "dist-test") execute_dist_tests ;; "system-test") execute_system_tests "check-kernel" "system-kmod-testsuite.log" ;; "system-test-userspace") execute_system_tests "check-system-userspace" \ "system-userspace-testsuite.log" ;; "system-test-dpdk") # The dpdk tests need huge page memory, so reserve some 2M pages. sudo bash -c "echo 2048 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages" execute_system_tests "check-system-dpdk" "system-dpdk-testsuite.log" ;; esac else configure_ovn $OPTS make $JOBS || { cat config.log; exit 1; } fi exit 0 ovn-25.09.0~git20250813.23884f5/.ci/linux-util.sh000077500000000000000000000032011504532661100202630ustar00rootroot00000000000000#!/bin/bash function free_up_disk_space_ubuntu() { local pkgs='azure-cli aspnetcore-* dotnet-* ghc-* firefox* google-chrome-stable google-cloud-cli libmono-* llvm-* microsoft-edge-stable mono-* msbuild mysql-server-core-* php-* php7* powershell* temurin-* zulu-*' # Use apt patterns to only select real packages that match the names # in the list above. local pkgs=$(echo $pkgs | sed 's/[^ ]* */~n&/g') sudo apt update && sudo apt-get --auto-remove -y purge $pkgs local paths='/usr/local/lib/android/ /usr/share/dotnet/ /opt/ghc/ /usr/local/share/boost/' sudo rm -rf $paths } function set_containers_apparmor_profile() { local profile=$1 sed -i "s/^#apparmor_profile = \".*\"$/apparmor_profile = \"$profile\"/" \ /usr/share/containers/containers.conf } # On multiple occasions GitHub added things to /etc/hosts that are not # a correct syntax for this file causing test failures: # https://github.com/actions/runner-images/issues/3353 # https://github.com/actions/runner-images/issues/12192 # Just clearing those out, if any. function fix_etc_hosts() { cp /etc/hosts ./hosts.bak sed -E -n \ '/^[[:space:]]*(#.*|[0-9a-fA-F:.]+([[:space:]]+[a-zA-Z0-9.-]+)+|)$/p' \ ./hosts.bak | sudo tee /etc/hosts diff -u ./hosts.bak /etc/hosts || true } # Workaround until https://github.com/actions/runner-images/issues/10015 # is resolved in some way. function disable_apparmor() { # https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/2093797 sudo aa-teardown || true sudo systemctl disable --now apparmor.service } ovn-25.09.0~git20250813.23884f5/.ci/osx-build.sh000077500000000000000000000014231504532661100200630ustar00rootroot00000000000000#!/bin/bash set -o errexit CFLAGS="-Werror $CFLAGS" EXTRA_OPTS="" function configure_ovs() { pushd ovs ./boot.sh && ./configure $* make -j4 || { cat config.log; exit 1; } popd } function configure_ovn() { configure_ovs $* ./boot.sh && ./configure $* } configure_ovn $EXTRA_OPTS $OPTS $* if [ "$CC" = "clang" ]; then set make CFLAGS="$CFLAGS -Wno-error=unused-command-line-argument" else set make CFLAGS="$CFLAGS $BUILD_ENV" fi if ! "$@"; then cat config.log exit 1 fi if [ "$TESTSUITE" ] && [ "$CC" != "clang" ]; then export DISTCHECK_CONFIGURE_FLAGS="$EXTRA_OPTS" if ! make distcheck RECHECK=yes; then # testsuite.log is necessary for debugging. cat */_build/sub/tests/testsuite.log exit 1 fi fi exit 0 ovn-25.09.0~git20250813.23884f5/.ci/osx-prepare.sh000077500000000000000000000001231504532661100204160ustar00rootroot00000000000000#!/bin/bash set -ev pip3 install --user six pip3 install --user --upgrade docutils ovn-25.09.0~git20250813.23884f5/.ci/ovn-kubernetes/000077500000000000000000000000001504532661100205655ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.ci/ovn-kubernetes/Dockerfile000066400000000000000000000077161504532661100225720ustar00rootroot00000000000000ARG OVNKUBE_COMMIT ARG GO_VERSION ARG FEDORA_VERSION FROM fedora:$FEDORA_VERSION AS ovnbuilder USER root ENV PYTHONDONTWRITEBYTECODE yes # install needed rpms - openvswitch must be 2.10.4 or higher RUN INSTALL_PKGS=" rpm-build dnf-plugins-core" && \ dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS # Build OVS and OVN rpms from current folder RUN mkdir /tmp/ovn COPY . /tmp/ovn WORKDIR /tmp/ovn/ovs RUN sed -e 's/@VERSION@/0.0.1/' rhel/openvswitch-fedora.spec.in > /tmp/ovs.spec RUN dnf builddep -y /tmp/ovs.spec RUN ./boot.sh RUN ./configure -v RUN make rpm-fedora RUN rm rpm/rpmbuild/RPMS/x86_64/*debug* RUN rm rpm/rpmbuild/RPMS/x86_64/*devel* WORKDIR /tmp/ovn RUN sed -e 's/@VERSION@/0.0.1/' rhel/ovn-fedora.spec.in > /tmp/ovn.spec RUN dnf builddep -y /tmp/ovn.spec RUN ./boot.sh RUN ./configure RUN make rpm-fedora RUN rm rpm/rpmbuild/RPMS/x86_64/*debug* RUN rm rpm/rpmbuild/RPMS/x86_64/*docker* # Build ovn-kubernetes ARG GO_VERSION FROM golang:$GO_VERSION as ovnkubebuilder ARG OVNKUBE_COMMIT ARG FEDORA_VERSION # Clone OVN Kubernetes and build the binary based on the commit passed as argument WORKDIR /root RUN git clone https://github.com/ovn-org/ovn-kubernetes.git WORKDIR /root/ovn-kubernetes RUN git checkout ${OVNKUBE_COMMIT} && git log -n 1 # Copy the ovn-kubernetes scripts from the OVN sources and apply any # custom changes if needed. RUN mkdir -p /tmp/ovn/.ci/ovn-kubernetes COPY .ci/ovn-kubernetes /tmp/ovn/.ci/ovn-kubernetes WORKDIR /tmp/ovn RUN .ci/ovn-kubernetes/prepare.sh /root/ovn-kubernetes /dev/null WORKDIR /root/ovn-kubernetes/go-controller # Get a working version of libovsdb (for modelgen). RUN GO111MODULE=on go install github.com/ovn-org/libovsdb/cmd/modelgen@$( \ go list -mod=mod -m -f '{{ .Version }}' github.com/ovn-org/libovsdb \ ) # Make sure we use the OVN NB/SB schema from the local code. COPY --from=ovnbuilder /tmp/ovn/ovn-nb.ovsschema pkg/nbdb/ovn-nb.ovsschema COPY --from=ovnbuilder /tmp/ovn/ovn-sb.ovsschema pkg/sbdb/ovn-sb.ovsschema RUN go generate ./pkg/nbdb && go generate ./pkg/sbdb && make # Build the final image FROM fedora:$FEDORA_VERSION # install needed dependencies RUN INSTALL_PKGS=" \ iptables iproute iputils hostname unbound-libs kubernetes-client kmod socat" && \ dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS RUN mkdir -p /var/run/openvswitch # install openvswitch and ovn rpms built in previous stages COPY --from=ovnbuilder /tmp/ovn/rpm/rpmbuild/RPMS/x86_64/*rpm ./ COPY --from=ovnbuilder /tmp/ovn/ovs/rpm/rpmbuild/RPMS/x86_64/*rpm ./ COPY --from=ovnbuilder /tmp/ovn/ovs/rpm/rpmbuild/RPMS/noarch/*rpm ./ RUN dnf install -y *.rpm && rm -f *.rpm # install ovn-kubernetes binaries built in previous stage RUN mkdir -p /usr/libexec/cni/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovnkube /usr/bin/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovnkube-identity /usr/bin/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-kube-util /usr/bin/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovndbchecker /usr/bin/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/go-controller/_output/go/bin/ovn-k8s-cni-overlay /usr/libexec/cni/ovn-k8s-cni-overlay # ovnkube.sh is the entry point. This script examines environment # variables to direct operation and configure ovn COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovnkube.sh /root/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/ovndb-raft-functions.sh /root/ COPY --from=ovnkubebuilder /root/ovn-kubernetes/dist/images/iptables-scripts /usr/sbin/ # Make some room. RUN REMOVE_PKGS="llvm-libs clang-libs" && \ dnf remove -y $REMOVE_PKGS && dnf clean all && rm -rf /var/cache/dnf/* LABEL io.k8s.display-name="ovn-kubernetes" \ io.k8s.description="This is a Kubernetes network plugin that provides an overlay network using OVN." \ maintainer="ovn team" WORKDIR /root ENTRYPOINT /root/ovnkube.sh ovn-25.09.0~git20250813.23884f5/.ci/ovn-kubernetes/custom.patch000066400000000000000000000000001504532661100231060ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.ci/ovn-kubernetes/prepare.sh000077500000000000000000000014441504532661100225650ustar00rootroot00000000000000#!/bin/bash set -ev ovnk8s_path=$1 env_path=$2 topdir=$PWD function extract_ci_var() { local name=$1 grep "$name:" .github/workflows/test.yml | awk '{print $2}' | tr -d '"' } pushd ${ovnk8s_path} # Add here any custom operations that need to performed on the # ovn-kubernetes cloned repo, e.g., custom patches. # Set up the right GO_VERSION and K8S_VERSION. echo "GO_VERSION=$(extract_ci_var GO_VERSION)" >> $env_path echo "K8S_VERSION=$(extract_ci_var K8S_VERSION)" >> $env_path # git apply --allow-empty is too new so not all git versions from major # distros support it, just check if the custom patch file is not empty # before applying it. [ -s ${topdir}/.ci/ovn-kubernetes/custom.patch ] && \ git apply -v ${topdir}/.ci/ovn-kubernetes/custom.patch popd # ${ovnk8s_path} exit 0 ovn-25.09.0~git20250813.23884f5/.cirrus.yml000066400000000000000000000032111504532661100172520ustar00rootroot00000000000000compute_engine_instance: image_project: ubuntu-os-cloud image: family/ubuntu-2404-lts-arm64 architecture: arm64 platform: linux memory: 4G # Run separate task for the image build, so it's running only once outside # the test matrix. build_image_task: install_dependencies_script: - sudo apt update - sudo apt install -y podman make build_container_script: - cd utilities/containers - make ubuntu - podman save -o /tmp/image.tar --format oci-archive ovn-org/ovn-tests:ubuntu upload_image_script: - curl -s -X POST -T /tmp/image.tar http://$CIRRUS_HTTP_CACHE_HOST/${CIRRUS_CHANGE_IN_REPO} arm_unit_tests_task: depends_on: - build_image env: CIRRUS_CLONE_SUBMODULES: true PATH: ${HOME}/bin:${HOME}/.local/bin:${PATH} RECHECK: yes IMAGE_NAME: ovn-org/ovn-tests:ubuntu matrix: - CC: gcc TESTSUITE: test TEST_RANGE: -300 - CC: gcc TESTSUITE: test TEST_RANGE: 301-600 - CC: gcc TESTSUITE: test TEST_RANGE: 601- UNSTABLE: yes - CC: clang TESTSUITE: test TEST_RANGE: -300 - CC: clang TESTSUITE: test TEST_RANGE: 301-600 - CC: clang TESTSUITE: test TEST_RANGE: 601- UNSTABLE: yes name: ARM64 ${CC} ${TESTSUITE} ${TEST_RANGE} install_dependencies_script: - sudo apt update - sudo apt install -y podman download_cache_script: - curl http://$CIRRUS_HTTP_CACHE_HOST/${CIRRUS_CHANGE_IN_REPO} -o /tmp/image.tar load_image_script: - podman load -i /tmp/image.tar - rm -rf /tmp/image.tar build_script: - ./.ci/ci.sh --archive-logs ovn-25.09.0~git20250813.23884f5/.github/000077500000000000000000000000001504532661100165055ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.github/workflows/000077500000000000000000000000001504532661100205425ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/.github/workflows/containers.yml000066400000000000000000000032771504532661100234430ustar00rootroot00000000000000name: Containers on: # Be able to run the job manually when needed workflow_dispatch: # Build every week on Monday 00:00 schedule: - cron: '0 0 * * 1' env: IMAGE_REGISTRY: ghcr.io IMAGE_NAMESPACE: ovn-org IMAGE_NAME: ovn-tests CONTAINERS_PATH: ./utilities/containers DEPENDENCIES: podman jobs: container: if: github.repository_owner == 'ovn-org' runs-on: ubuntu-24.04 strategy: matrix: distro: [ fedora, ubuntu ] steps: - uses: actions/checkout@v4 - name: Update APT cache run: sudo apt update - name: Install dependencies run: sudo apt install -y ${{ env.DEPENDENCIES }} - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Build container images id: build-image uses: redhat-actions/buildah-build@v2 with: image: ${{ env.IMAGE_NAME }} archs: amd64, arm64 tags: ${{ matrix.distro }} build-args: CONTAINERS_PATH=${{ env.CONTAINERS_PATH }} dockerfiles: ${{ env.CONTAINERS_PATH }}/${{ matrix.distro }}/Dockerfile - name: Push to ghcr.io id: push-to-registry uses: redhat-actions/push-to-registry@v2 with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} registry: ${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAMESPACE }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Print image url run: echo "Image pushed to ${{ steps.push-to-registry.outputs.registry-paths }}" ovn-25.09.0~git20250813.23884f5/.github/workflows/ovn-fake-multinode-tests.yml000066400000000000000000000175241504532661100261420ustar00rootroot00000000000000name: System tests using ovn-fake-multinode on: schedule: # Run everyday at midnight - cron: '0 0 * * *' workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: build: name: Build ovn-fake-multinode image if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule' runs-on: ubuntu-24.04 strategy: matrix: cfg: - { repo: "${{ github.repository }}", branch: "${{ github.ref_name }}" } - { repo: ovn-org/ovn, branch: "branch-24.03" } env: RUNC_CMD: podman OS_IMAGE: "fedora:42" # https://github.com/actions/runner-images/issues/6282 XDG_RUNTIME_DIR: '' steps: - name: Check out ovn-fake-multi-node uses: actions/checkout@v4 with: repository: 'ovn-org/ovn-fake-multinode' path: 'ovn-fake-multinode' ref: 'v0.4' # Check out ovn and ovs separately inside ovn-fake-multinode/ovn and ovn-fake-multinode/ovs # ovn-fake-multinode builds and installs ovs from ovn-fake-multinode/ovs # and it builds and installs ovn from ovn-fake-multinode/ovn. It uses the ovs submodule for ovn compilation. - name: Check out ovs main uses: actions/checkout@v4 with: path: 'ovn-fake-multinode/ovs' repository: 'openvswitch/ovs' ref: 'main' - name: Check out ovn ${{ matrix.cfg.branch }} of ${{ matrix.cfg.repo }} uses: actions/checkout@v4 with: path: 'ovn-fake-multinode/ovn' submodules: recursive repository: ${{ matrix.cfg.repo }} ref: ${{ matrix.cfg.branch }} - name: Install dependencies run: | sudo apt update || true sudo apt-get install -y podman - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts working-directory: ovn-fake-multinode/ovn - name: Disable apparmor run: | . .ci/linux-util.sh disable_apparmor working-directory: ovn-fake-multinode/ovn - name: Build ovn-fake-multi-node ${{ matrix.cfg.branch }} image run: | set -x sudo -E ./ovn_cluster.sh build mkdir -p /tmp/_output sudo podman tag ovn/ovn-multi-node:latest ovn/ovn-multi-node:${{ matrix.cfg.branch }} sudo podman save --format oci-archive ovn/ovn-multi-node:${{ matrix.cfg.branch }} > /tmp/_output/ovn_${{ matrix.cfg.branch }}_image.tar working-directory: ovn-fake-multinode - uses: actions/upload-artifact@v4 with: name: test-${{ matrix.cfg.branch }}-image path: /tmp/_output/ovn_${{ matrix.cfg.branch }}_image.tar multinode-tests: runs-on: ubuntu-24.04 timeout-minutes: 30 needs: [build] strategy: fail-fast: false matrix: cfg: - { branch: "${{ github.ref_name }}", testsuiteflags: ""} - { branch: "branch-24.03", testsuiteflags: "-k 'basic test'" } name: multinode tests ${{ join(matrix.cfg.*, ' ') }} env: RUNC_CMD: podman OS_IMAGE: "fedora:42" CENTRAL_IMAGE: "ovn/ovn-multi-node:${{ matrix.cfg.branch }}" CHASSIS_IMAGE: "ovn/ovn-multi-node:${{ github.ref_name }}" RELAY_IMAGE: "ovn/ovn-multi-node:${{ github.ref_name }}" GW_IMAGE: "ovn/ovn-multi-node:${{ github.ref_name }}" # Disable SSL/TLS for now. Revisit this if required. ENABLE_SSL: no CC: gcc OPTS: "--disable-ssl" dependencies: | automake libtool gcc bc libjemalloc2 libjemalloc-dev \ libssl-dev llvm-dev libelf-dev libnuma-dev libpcap-dev \ selinux-policy-dev ncat python3-scapy isc-dhcp-server \ podman openvswitch-switch libunbound-dev libunwind-dev # https://github.com/actions/runner-images/issues/6282 XDG_RUNTIME_DIR: '' steps: - name: Check out ovn uses: actions/checkout@v4 - name: install required dependencies run: | sudo apt update || true sudo apt install -y ${{ env.dependencies }} sudo apt install -y linux-modules-extra-$(uname -r) - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Disable apparmor run: | . .ci/linux-util.sh disable_apparmor - name: Free up disk space run: | . .ci/linux-util.sh free_up_disk_space_ubuntu - name: Set podman apparmor=unconfined run: | . .ci/linux-util.sh set_containers_apparmor_profile unconfined - uses: actions/download-artifact@v4 with: name: test-${{ github.ref_name }}-image - uses: actions/download-artifact@v4 with: name: test-branch-24.03-image - name: Load podman image run: | sudo podman load --input ovn_${{ github.ref_name }}_image.tar sudo podman load --input ovn_branch-24.03_image.tar - name: Check out ovn-fake-multi-node uses: actions/checkout@v4 with: repository: 'ovn-org/ovn-fake-multinode' path: 'ovn-fake-multinode' ref: 'v0.4' - name: Start openvswitch run: | sudo systemctl start openvswitch-switch sudo ovs-vsctl show - name: Start basic cluster run: | sudo -E CHASSIS_COUNT=4 GW_COUNT=4 ./ovn_cluster.sh start sudo podman exec -it ovn-central-az1 ovn-nbctl show sudo podman exec -it ovn-central-az1 ovn-appctl -t ovn-northd version sudo podman exec -it ovn-chassis-1 ovn-appctl -t ovn-controller version working-directory: ovn-fake-multinode - name: Run basic test script run: | sudo ./.ci/test_basic.sh working-directory: ovn-fake-multinode - name: update PATH run: | echo "$HOME/bin" >> $GITHUB_PATH echo "$HOME/.local/bin" >> $GITHUB_PATH - name: set up python uses: actions/setup-python@v5 with: python-version: '3.12' - name: Check out ovn uses: actions/checkout@v4 with: path: 'ovn' submodules: recursive - name: Build OVN (for running fake-multinode system tests) run: | pip3 install --disable-pip-version-check --user wheel pip3 install --disable-pip-version-check --user \ -r utilities/containers/py-requirements.txt USE_SPARSE=no ./.ci/linux-build.sh working-directory: ovn - name: Run fake-multinode system tests run: | if ! sudo -E make check-multinode TESTSUITEFLAGS="${{ matrix.cfg.testsuiteflags }}"; then sudo podman exec -it ovn-central-az1 ovn-nbctl show || : sudo podman exec -it ovn-central-az1 ovn-sbctl show || : sudo podman exec -it ovn-chassis-1 ovs-vsctl show || : sudo podman exec -it ovn-chassis-1 ip netns || : sudo podman exec -it ovn-chassis-1 cat /var/log/ovn/ovn-controller.log || : sudo cat tests/multinode-testsuite.log || : exit 1 fi working-directory: ovn - name: copy logs on failure if: failure() || cancelled() run: | # upload-artifact throws exceptions if it tries to upload socket # files and we could have some socket files in testsuite.dir. # Also, upload-artifact doesn't work well enough with wildcards. # So, we're just archiving everything here to avoid any issues. mkdir logs cp ovn/config.log ./logs/ # multinode tests are run as root, need to adjust permissions. sudo chmod -R +r ovn/tests/multinode-testsuite.* || true cp -r ovn/tests/multinode-testsuite.* ./logs/ || true tar -czvf logs.tgz logs/ - name: upload logs on failure if: failure() || cancelled() uses: actions/upload-artifact@v4 with: name: logs-linux-${{ join(matrix.cfg.*, '-') }} path: logs.tgz - name: Stop cluster run: | sudo -E ./ovn_cluster.sh stop working-directory: ovn-fake-multinode ovn-25.09.0~git20250813.23884f5/.github/workflows/ovn-kubernetes.yml000066400000000000000000000151601504532661100242370ustar00rootroot00000000000000name: ovn-kubernetes on: push: pull_request: workflow_dispatch: schedule: # Run Sunday at midnight - cron: '0 0 * * 0' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true env: OVNKUBE_COMMIT: "release-1.0" KIND_CLUSTER_NAME: ovn KIND_INSTALL_INGRESS: true KIND_ALLOW_SYSTEM_WRITES: true # This skips tests tagged as Serial # Current Serial tests are not relevant for OVN PARALLEL: true jobs: build: name: Build if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule' runs-on: ubuntu-24.04 steps: - name: Enable Docker experimental features run: | echo $'{"experimental": true}' | sudo tee /etc/docker/daemon.json sudo service docker restart - name: Check out ovn uses: actions/checkout@v4 with: submodules: recursive - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Check out ovn-kubernetes uses: actions/checkout@v4 with: path: src/github.com/ovn-org/ovn-kubernetes repository: ovn-org/ovn-kubernetes ref: ${{ env.OVNKUBE_COMMIT }} - name: Prepare run: | .ci/ovn-kubernetes/prepare.sh src/github.com/ovn-org/ovn-kubernetes $GITHUB_ENV - name: Build ovn-kubernetes container run: | docker build --build-arg OVNKUBE_COMMIT=${{ env.OVNKUBE_COMMIT }} \ --build-arg GO_VERSION=${{ env.GO_VERSION }} \ --build-arg FEDORA_VERSION=42 \ --squash -t ovn-daemonset-f:dev -f .ci/ovn-kubernetes/Dockerfile . mkdir /tmp/_output docker save ovn-daemonset-f:dev > /tmp/_output/image.tar - uses: actions/upload-artifact@v4 with: name: test-image path: /tmp/_output/image.tar e2e: name: e2e if: github.event_name != 'schedule' runs-on: ubuntu-24.04 timeout-minutes: 220 strategy: fail-fast: false matrix: # Valid options are: # target: ["shard-conformance", "control-plane" ] # shard-conformance: hybrid-overlay = multicast-enable = emptylb-enable = false # control-plane: hybrid-overlay = multicast-enable = emptylb-enable = true # gateway-mode: ["local", "shared"] # ipfamily: ["ipv4", "ipv6", "dualstack"] # disable-snat-multiple-gws: ["noSnatGW", "snatGW"] include: - {"target": "shard-conformance", "ha": "HA", "gateway-mode": "local", "ipfamily": "ipv6", "disable-snat-multiple-gws": "snatGW"} - {"target": "shard-conformance", "ha": "HA", "gateway-mode": "local", "ipfamily": "dualstack", "disable-snat-multiple-gws": "snatGW"} - {"target": "shard-conformance", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW"} - {"target": "shard-conformance", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv6", "disable-snat-multiple-gws": "snatGW"} - {"target": "control-plane", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "noSnatGW"} - {"target": "control-plane", "ha": "HA", "gateway-mode": "shared", "ipfamily": "ipv4", "disable-snat-multiple-gws": "snatGW"} needs: [build] env: JOB_NAME: "${{ matrix.target }}-${{ matrix.ha }}-${{ matrix.gateway-mode }}-${{ matrix.ipfamily }}-${{ matrix.disable-snat-multiple-gws }}-${{ matrix.second-bridge }}" OVN_HYBRID_OVERLAY_ENABLE: "${{ matrix.target == 'control-plane' }}" KIND_INSTALL_METALLB: "${{ matrix.target == 'control-plane' }}" OVN_MULTICAST_ENABLE: "${{ matrix.target == 'control-plane' }}" OVN_EMPTY_LB_EVENTS: "${{ matrix.target == 'control-plane' }}" OVN_HA: "true" OVN_DISABLE_SNAT_MULTIPLE_GWS: "${{ matrix.disable-snat-multiple-gws == 'noSnatGW' }}" OVN_GATEWAY_MODE: "${{ matrix.gateway-mode }}" KIND_IPV4_SUPPORT: "${{ matrix.ipfamily == 'IPv4' || matrix.ipfamily == 'dualstack' }}" KIND_IPV6_SUPPORT: "${{ matrix.ipfamily == 'IPv6' || matrix.ipfamily == 'dualstack' }}" steps: - name: Check out ovn uses: actions/checkout@v4 - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Free up disk space run: | . .ci/linux-util.sh free_up_disk_space_ubuntu - name: Check out ovn-kubernetes uses: actions/checkout@v4 with: path: src/github.com/ovn-org/ovn-kubernetes repository: ovn-org/ovn-kubernetes ref: ${{ env.OVNKUBE_COMMIT }} - name: Prepare run: | .ci/ovn-kubernetes/prepare.sh src/github.com/ovn-org/ovn-kubernetes $GITHUB_ENV - name: Set up Go uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache-dependency-path: "**/*.sum" id: go - name: Set up GOPATH run: | export GOPATH=$(go env GOPATH) echo "GOPATH=$GOPATH" >> $GITHUB_ENV echo "$GOPATH/bin" >> $GITHUB_PATH - name: Disable ufw # For IPv6 and Dualstack, ufw (Uncomplicated Firewall) should be disabled. # Not needed for KIND deployments, so just disable all the time. run: | sudo ufw disable - uses: actions/download-artifact@v4 with: name: test-image - name: Load docker image run: | docker load --input image.tar && rm -rf image.tar - name: kind setup run: | export OVN_IMAGE="ovn-daemonset-f:dev" make -C test install-kind working-directory: src/github.com/ovn-org/ovn-kubernetes - name: Run Tests # e2e tests take ~60 minutes normally, 120 should be more than enough # set 180 for control-plane tests as these might take a while timeout-minutes: ${{ matrix.target == 'control-plane' && 180 || 120 }} run: | make -C test ${{ matrix.target }} working-directory: src/github.com/ovn-org/ovn-kubernetes - name: Upload Junit Reports if: always() uses: actions/upload-artifact@v4 with: name: kind-junit-${{ env.JOB_NAME }}-${{ github.run_id }} path: 'src/github.com/ovn-org/ovn-kubernetes/test/_artifacts/*.xml' - name: Export logs if: always() run: | mkdir -p /tmp/kind/logs kind export logs --name ${KIND_CLUSTER_NAME} --loglevel=debug /tmp/kind/logs working-directory: src/github.com/ovn-org/ovn-kubernetes - name: Upload logs if: always() uses: actions/upload-artifact@v4 with: name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }} path: /tmp/kind/logs ovn-25.09.0~git20250813.23884f5/.github/workflows/test.yml000066400000000000000000000240571504532661100222540ustar00rootroot00000000000000name: Build and Test on: push: pull_request: schedule: # Run Sunday at midnight - cron: '0 0 * * 0' concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} cancel-in-progress: true jobs: prepare-container: # This job has the following matrix, x: Job trigger, y: Branch # (scheduled jobs run only on main): # +-------+-------------------+-------------------+ # | | Push/Pull request | Scheduled | # +-------+-------------------+-------------------+ # | main | ghcr.io - Ubuntu | ghcr.io - Fedora | # +-------+-------------------+-------------------+ # | !main | Builds - Ubuntu | xxxxxxxxxxxxxxxxx | # +-------+-------------------+-------------------+ env: DEPENDENCIES: podman name: Prepare container if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule' runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - name: Update APT cache run: sudo apt update - name: Install dependencies run: sudo apt install -y ${{ env.DEPENDENCIES }} - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Disable apparmor run: | . .ci/linux-util.sh disable_apparmor - name: Choose image distro if: github.event_name == 'push' || github.event_name == 'pull_request' run: | echo "IMAGE_DISTRO=ubuntu" >> $GITHUB_ENV - name: Choose image distro if: github.event_name == 'schedule' run: | echo "IMAGE_DISTRO=fedora" >> $GITHUB_ENV - name: Build container if: github.ref_name != 'main' run: make ${{ env.IMAGE_DISTRO }} working-directory: utilities/containers - name: Download container if: github.ref_name == 'main' run: podman pull ghcr.io/ovn-org/ovn-tests:${{ env.IMAGE_DISTRO }} - name: Tag image run: podman tag ovn-org/ovn-tests:${{ env.IMAGE_DISTRO }} ovn-org/ovn-tests - name: Export image run: podman save -o /tmp/image.tar --format oci-archive ovn-org/ovn-tests - name: Cache image id: image_cache uses: actions/cache@v4 with: path: /tmp/image.tar key: ${{ github.sha }}/${{ github.event_name }} build-linux: needs: [prepare-container] env: ARCH: ${{ matrix.cfg.arch }} CC: ${{ matrix.cfg.compiler }} DPDK: ${{ matrix.cfg.dpdk }} LIBS: ${{ matrix.cfg.libs }} OPTS: ${{ matrix.cfg.opts }} TESTSUITE: ${{ matrix.cfg.testsuite }} TEST_RANGE: ${{ matrix.cfg.test_range }} SANITIZERS: ${{ matrix.cfg.sanitizers }} UNSTABLE: ${{ matrix.cfg.unstable }} name: linux ${{ join(matrix.cfg.*, ' ') }} runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: cfg: - { compiler: gcc, opts: --disable-ssl } - { compiler: clang, opts: --disable-ssl } - { compiler: gcc, testsuite: dist-test } - { compiler: gcc, testsuite: test, test_range: "-300" } - { compiler: gcc, testsuite: test, test_range: "301-600" } - { compiler: gcc, testsuite: test, test_range: "601-", unstable: unstable } - { compiler: clang, testsuite: test, sanitizers: sanitizers, test_range: "-300" } - { compiler: clang, testsuite: test, sanitizers: sanitizers, test_range: "301-600" } - { compiler: clang, testsuite: test, sanitizers: sanitizers, test_range: "601-", unstable: unstable } - { compiler: gcc, testsuite: test, libs: -ljemalloc, test_range: "-300" } - { compiler: gcc, testsuite: test, libs: -ljemalloc, test_range: "301-600" } - { compiler: gcc, testsuite: test, libs: -ljemalloc, test_range: "601-", unstable: unstable } - { compiler: gcc, testsuite: system-test-dpdk, dpdk: dpdk, test_range: "-100" } - { compiler: gcc, testsuite: system-test-dpdk, dpdk: dpdk, test_range: "101-200" } - { compiler: gcc, testsuite: system-test-dpdk, dpdk: dpdk, test_range: "201-", unstable: unstable } - { compiler: gcc, testsuite: system-test-userspace, test_range: "-100" } - { compiler: gcc, testsuite: system-test-userspace, test_range: "101-200" } - { compiler: gcc, testsuite: system-test-userspace, test_range: "201-", unstable: unstable } - { compiler: gcc, testsuite: system-test, test_range: "-100" } - { compiler: gcc, testsuite: system-test, test_range: "101-200" } - { compiler: gcc, testsuite: system-test, test_range: "201-", unstable: unstable } - { compiler: clang, testsuite: system-test, sanitizers: sanitizers, test_range: "-100" } - { compiler: clang, testsuite: system-test, sanitizers: sanitizers, test_range: "101-200" } - { compiler: clang, testsuite: system-test, sanitizers: sanitizers, test_range: "201-", unstable: unstable } - { arch: x86, compiler: gcc, opts: --disable-ssl } steps: - name: system-level-dependencies if: ${{ startsWith(matrix.cfg.testsuite, 'system-test') }} run: | sudo apt update sudo apt -y install linux-modules-extra-$(uname -r) - name: checkout if: github.event_name == 'push' || github.event_name == 'pull_request' uses: actions/checkout@v4 with: submodules: recursive # For weekly runs, don't update submodules - name: checkout without submodule if: github.event_name == 'schedule' uses: actions/checkout@v4 # Weekly runs test using the tip of the most recent stable OVS branch # instead of the submodule. - name: checkout OVS if: github.event_name == 'schedule' uses: actions/checkout@v4 with: repository: 'openvswitch/ovs' fetch-depth: 0 path: 'ovs' - name: checkout OVS most recent stable branch. if: github.event_name == 'schedule' run: | git checkout \ $(git branch -a -l '*branch-*' | sed 's/remotes\/origin\///' | \ sort -V | tail -1) working-directory: ovs - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: Disable apparmor run: | . .ci/linux-util.sh disable_apparmor - name: image cache id: image_cache uses: actions/cache@v4 with: path: /tmp/image.tar key: ${{ github.sha }}/${{ github.event_name }} - name: load image run: | sudo podman load -i /tmp/image.tar podman load -i /tmp/image.tar rm -rf /tmp/image.tar - name: build if: ${{ startsWith(matrix.cfg.testsuite, 'system-test') }} run: sudo -E ./.ci/ci.sh --archive-logs --timeout=2h - name: build if: ${{ !startsWith(matrix.cfg.testsuite, 'system-test') }} run: ./.ci/ci.sh --archive-logs --timeout=2h - name: upload logs on failure if: failure() || cancelled() uses: actions/upload-artifact@v4 with: name: logs-linux-${{ join(matrix.cfg.*, '-') }} path: logs.tgz build-osx: env: CC: clang OPTS: --disable-ssl name: osx clang --disable-ssl if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule' runs-on: macos-latest strategy: fail-fast: false steps: - name: checkout if: github.event_name == 'push' || github.event_name == 'pull_request' uses: actions/checkout@v4 with: submodules: recursive # For weekly runs, don't update submodules - name: checkout without submodule if: github.event_name == 'schedule' uses: actions/checkout@v4 # Weekly runs test using the tip of the most recent stable OVS branch # instead of the submodule. - name: checkout OVS if: github.event_name == 'schedule' uses: actions/checkout@v4 with: repository: 'openvswitch/ovs' fetch-depth: 0 path: 'ovs' - name: checkout OVS most recent stable branch. if: github.event_name == 'schedule' run: | git checkout \ $(git branch -a -l '*branch-*' | sed 's/remotes\/origin\///' | \ sort -V | tail -1) working-directory: ovs - name: install dependencies run: brew install automake libtool - name: update PATH run: | echo "$HOME/bin" >> $GITHUB_PATH echo "$HOME/.local/bin" >> $GITHUB_PATH - name: set up python uses: actions/setup-python@v5 with: python-version: '3.12' - name: prepare run: ./.ci/osx-prepare.sh - name: build run: ./.ci/osx-build.sh - name: upload logs on failure if: failure() uses: actions/upload-artifact@v4 with: name: logs-osx-clang---disable-ssl path: config.log build-linux-rpm: name: linux rpm fedora if: github.repository_owner == 'ovn-org' || github.event_name != 'schedule' runs-on: ubuntu-24.04 container: fedora:42 timeout-minutes: 30 strategy: fail-fast: false steps: - name: install dependencies run: dnf install -y dnf-plugins-core git rpm-build - name: checkout uses: actions/checkout@v4 with: submodules: recursive - name: install build dependencies run: | sed -e 's/@VERSION@/0.0.1/' rhel/ovn-fedora.spec.in \ > /tmp/ovn.spec dnf builddep -y /tmp/ovn.spec - name: Fix /etc/hosts file run: | . .ci/linux-util.sh fix_etc_hosts - name: configure OvS run: ./boot.sh && ./configure working-directory: ovs - name: make dist OvS run: make dist working-directory: ovs - name: configure OVN run: ./boot.sh && ./configure - name: make dist OVN run: make dist - name: build RPM run: make rpm-fedora - name: upload rpm packages uses: actions/upload-artifact@v4 with: name: rpm-packages path: | rpm/rpmbuild/SRPMS/*.rpm rpm/rpmbuild/RPMS/*/*.rpm retention-days: 14 ovn-25.09.0~git20250813.23884f5/.gitignore000066400000000000000000000020201504532661100171270ustar00rootroot00000000000000#*# *.a *.d *.gcno *.gcda *.ko *.la *.lo *.loT *.mod.c *.o *.obj *.exe *.exp *.ilk *.lib *.pdb *.pyc *.retry *.so *.suo **/*.sym *~ *,cover .#* .*.cmd .*.swp .coverage .deps .dirstamp .libs .tmp_versions .vagrant /Makefile /Makefile.in /aclocal.m4 /ovs-distfiles /datapath-distfiles /all-distfiles /all-gitfiles /autom4te.cache /build-arch-stamp /build-indep-stamp /compile /config.guess /config.h /config.h.in /config.log /config.status /config.sub /configure /configure-stamp /depcomp /distfiles /dist-docs /flake8-check /docs-check /install-sh /libtool /manpage-check /missing /missing-distfiles /ovn-architecture.7 /ovn-nb.5 /ovn-nb.gv /ovn-nb.pic /ovn-sb.5 /ovn-sb.gv /ovn-sb.pic /ovn-ic-nb.5 /ovn-ic-nb.gv /ovn-ic-nb.pic /ovn-ic-sb.5 /ovn-ic-sb.gv /ovn-ic-sb.pic /package.m4 /stamp-h1 /_build-gcc /_build-clang Module.symvers TAGS cscope.* tags _debian odp-netlink.h odp-netlink-macros.h OvsDpInterface.h /.vagrant/ testsuite.tmp.orig /rpm/ /openvswitch*.tar.gz /tests/lcov/ /Documentation/_build /.venv /cxx-check /*.ovsschema.stamp ovn-25.09.0~git20250813.23884f5/.gitmodules000066400000000000000000000001141504532661100173160ustar00rootroot00000000000000[submodule "ovs"] path = ovs url = https://github.com/openvswitch/ovs.git ovn-25.09.0~git20250813.23884f5/.mailmap000066400000000000000000000113131504532661100165650ustar00rootroot00000000000000# See git-shortlog(1) for official documentation of this file format. # # Name # Use "Name" for any commit with address "". This is useful when a person # has commits using different spellings of their name, but with the same email # address. # # Name # Use "Name" and "" for any commit with the address "". This is useful # when a person has used more than one email address. Aaron Conole Aaron Conole Aaron Rosen Alex Wang Alexey I. Froloff Alin Serdean Alin Serdean Andy Zhou Andy Zhou Andy Zhou Ansis Atteka Ansis Atteka Anupam Chanda Ariel Tubaltsev Babu Shanmugam Ben Pfaff Bruce Davie Bruce Davie Chandra Sekhar Vejendla Daniele Di Proietto Daniele Di Proietto Ed Maste Ethan J. Jackson Fischetti, Antonio Flavio Fernandes Flavio Leitner Gal Sagie Gurucharan Shetty Gurucharan Shetty Han Zhou Han Zhou Henry Mai Hui Kang Ian Campbell James Page Jarno Rajahalme Jarno Rajahalme Jean Tourrilhes Jean Tourrihles Jean Tourrilhes Jesse Gross Joe Stringer Joe Stringer Justin Pettit Kmindg Kyle Mestery Mark Gray Mauricio Vasquez Miguel Angel Ajo Neil McKee Ofer Ben-Yacov Polehn, Mike A Pravin B Shelar Raju Subramanian Ralf Spenneberg Rami Rosen Ramu Ramamurthy Robert Ã…kerblom-Andersson Roberto Bartzen Acosta Romain Lenglet Romain Lenglet Rosemarie O'Riorden Russell Bryant Ryan Moats Sabyasachi Sengupta Saurabh Shah Shad Ansari Shih-Hao Li Simon Horman Simon Horman Simon Horman Stephen Finucane Thomas F. Herbert Thomas Graf Thomas Graf Wei Li YAMAMOTO Takashi YAMAMOTO Takashi YAMAMOTO Takashi Zhi Yong Wu Zoltan Kiss Zong Kai LI ovn-25.09.0~git20250813.23884f5/.readthedocs.yaml000066400000000000000000000010641504532661100203750ustar00rootroot00000000000000# .readthedocs.yaml # Read the Docs configuration file. # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details. # Required. version: 2 # Set the OS, Python version, etc. build: os: ubuntu-22.04 tools: python: "3.12" # Build documentation in the "Documentation/" directory with Sphinx. sphinx: configuration: Documentation/conf.py # Default HTML builder. builder: "html" # Build all formats: HTML, PDF, ePub. formats: all # Declare the Python requirements. python: install: - requirements: Documentation/requirements.txt ovn-25.09.0~git20250813.23884f5/AUTHORS.rst000066400000000000000000001115361504532661100170330ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======= Authors ======= The following people authored or signed off on commits in the OVN source code or webpage version control repository. Since OVN originated in the Open vSwitch git repository, this list also includes all of the names in the AUTHORS file at the time OVN was split out from OVS. ================================== =============================================== Name Email ================================== =============================================== Aaron Conole aconole@redhat.com Aaron Rosen arosen@clemson.edu Abhiram R N abhiramrn@gmail.com Aditya Mehakare aditya.mehakare@nutanix.com Aidan Shribman aidan.shribman@gmail.com Alan Pevec alan.pevec@redhat.com Ales Musil amusil@redhat.com Alexander Duyck alexander.h.duyck@redhat.com Aleksandr Smirnov AleksSmirnov@k2.cloud Alexandra Rukomoinikova arukomoinikova@k2.cloud Alexandru Copot alex.mihai.c@gmail.com Alexei Starovoitov ast@plumgrid.com Alexey I. Froloff raorn@raorn.name Alexey Roytman roytman@il.ibm.com Alex Wang ee07b291@gmail.com Alfredo Finelli alf@computationes.de Alin Balutoiu abalutoiu@cloudbasesolutions.com Alin Serdean aserdean@cloudbasesolutions.com Ambika Arora ambika.arora@tcs.com Amit Bose bose@noironetworks.com Amitabha Biswas azbiswas@gmail.com Anand Kumar kumaranand@vmware.com Andrea Kao eirinikos@gmail.com Andreas Karis akaris@redhat.com Andrew Evans Andrew Beekhof abeekhof@redhat.com Andrew Kampjes a.kampjes@gmail.com Andrew Lambeth alambeth@vmware.com Andre McCurdy armccurdy@gmail.com Andy Hill hillad@gmail.com Andy Southgate andy.southgate@citrix.com Andy Zhou azhou@ovn.org Ankur Sharma ankursharma@vmware.com Anoob Soman anoob.soman@citrix.com Ansis Atteka aatteka@vmware.com Antonio Fischetti antonio.fischetti@intel.com Antonio Ojea antonio.ojea.garcia@gmail.com Anupam Chanda Ariel Tubaltsev atubaltsev@vmware.com Arnoldo Lutz arnoldo.lutz.guevara@hpe.com Artem Teleshev artem.teleshev@gmail.com Arun Sharma arun.sharma@calsoftinc.com Aryan TaheriMonfared aryan.taherimonfared@uis.no Asaf Penso asafp@mellanox.com Ashish Varma ashishvarma.ovs@gmail.com Ashwin Swaminathan ashwinds@arista.com Babu Shanmugam bschanmu@redhat.com Bala Sankaran bsankara@redhat.com Ben Pfaff blp@ovn.org Ben Warren ben@skyportsystems.com Benli Ye daniely@vmware.com Bert Vermeulen bert@biot.com Bhanuprakash Bodireddy bhanuprakash.bodireddy@intel.com Billy O'Mahony billy.o.mahony@intel.com Binbin Xu xu.binbin1@zte.com.cn Brian Haley haleyb.dev@gmail.com Brian Kruger bkruger+ovsdev@gmail.com Bruce Davie bdavie@vmware.com Bryan Phillippe bp@toroki.com Carlo Andreotti c.andreotti@m3s.it Casey Barker crbarker@google.com Chandra Sekhar Vejendla csvejend@us.ibm.com Christoph Jaeger cj@linux.com Chris Wright chrisw@sous-sol.org Chuck Short zulcss@ubuntu.com Ciara Loftus ciara.loftus@intel.com Clint Byrum clint@fewbar.com Cong Wang amwang@redhat.com Conner Herriges conner.herriges@ibm.com Damien Millescamps damien.millescamps@6wind.com Damijan Skvarc damjan.skvarc@gmail.com Dan Carpenter dan.carpenter@oracle.com Dan McGregor dan.mcgregor@usask.ca Dan Wendlandt Dan Williams dcbw@redhat.com Daniel Alvarez dalvarez@redhat.com Daniel Borkmann dborkman@redhat.com Daniel Hiltgen daniel@netkine.com Daniel Roman Daniele Di Proietto daniele.di.proietto@gmail.com Daniele Venturino venturino.daniele+ovs@gmail.com Danny Kukawka danny.kukawka@bisect.de Darrell Ball dlu998@gmail.com Dave Tucker dave@dtucker.co.uk David Erickson derickso@stanford.edu David Hill dhill@redhat.com David Marchand david.marchand@redhat.com David S. Miller davem@davemloft.net David Yang davidy@vmware.com Dennis Sam dsam@arista.com Devendra Naga devendra.aaru@gmail.com Dmitry Krivenok krivenok.dmitry@gmail.com Dominic Curran dominic.curran@citrix.com Dongdong dongdong1@huawei.com Dongjun dongj@dtdream.com Duan Jiong djduanjiong@gmail.com Duffie Cooley Dumitru Ceara dceara@redhat.com Dustin Lundquist dustin@null-ptr.net Ed Maste emaste@freebsd.org Ed Swierk eswierk@skyportsystems.com Edouard Bourguignon madko@linuxed.net Eelco Chaudron echaudro@redhat.com Eli Britstein elibr@mellanox.com Eric Lapointe elapointe@corsa.com Esteban Rodriguez Betancourt estebarb@hpe.com Aymerich Edward edward.aymerich@hpe.com Edward Tomasz NapieraÅ‚a trasz@freebsd.org Eitan Eliahu eliahue@vmware.com Enrique Llorente ellorent@redhat.com Eohyung Lee liquidnuker@gmail.com Eric Dumazet edumazet@google.com Eric Garver e@erig.me Eric Sesterhenn eric.sesterhenn@lsexperts.de Ethan J. Jackson ejj@eecs.berkeley.edu Ethan Rahn erahn@arista.com Evgenii Kovalev ekovalev.off@gmail.com Eziz Durdyyev ezizdurdy@gmail.com Fabrizio D'Angelo fdangelo@redhat.com Felix Huettner felix.huettner@mail.schwarz Flavio Fernandes flavio@flaviof.com Flavio Leitner fbl@redhat.com Francesco Fusco ffusco@redhat.com François Rigault frigo@amadeus.com Frank Wang wangpeihuixyz@126.com Frédéric Tobias Christ fchrist@live.de Frode Nordahl frode.nordahl@gmail.com FUJITA Tomonori fujita.tomonori@lab.ntt.co.jp Gabe Beged-Dov gabe@begeddov.com Gabriele Cerami gcerami@redhat.com Gaetano Catalli gaetano.catalli@gmail.com Gal Sagie gal.sagie@gmail.com Genevieve LEsperance glesperance@pivotal.io Geoffrey Wossum gwossum@acm.org Gianluca Merlo gianluca.merlo@gmail.com Giuseppe Lettieri g.lettieri@iet.unipi.it Glen Gibb grg@stanford.edu Gongming Chen gmingchen@tencent.com Guoshuai Li ligs@dtdream.com Guolin Yang gyang@vmware.com Guru Chaitanya Perakam gperakam@Brocade.com Gurucharan Shetty guru@ovn.org Han Zhou hzhou@ovn.org Henry Mai Hao Zheng Helmut Schaa helmut.schaa@googlemail.com Hiteshi Kalra hiteshi.kalra@tcs.com Huanle Han hanxueluo@gmail.com Hui Kang kangh@us.ibm.com Hyong Youb Kim hyonkim@cisco.com Ian Campbell Ian.Campbell@citrix.com Ian Stokes ian.stokes@intel.com Igal Tsoiref itsoiref@redhat.com Igor Zhukov ivzhukov@sbercloud.ru Ihar Hrachyshka ihrachys@redhat.com Ihtisham ul Haq Ihtisham.ul_Haq@mail.schwarz Ilya Maximets i.maximets@samsung.com Iman Tabrizian tabrizian@outlook.com Isaku Yamahata yamahata@valinux.co.jp Ivan Dyukov i.dyukov@samsung.com IWASE Yusuke iwase.yusuke@gmail.com Jakub Libosvar libosvar@redhat.com Jakub Sitnicki jsitnicki@gmail.com James P. roampune@gmail.com James Page james.page@ubuntu.com James Troup james.troup@canonical.com Jamie Lennox jamielennox@gmail.com Jan Scheurich jan.scheurich@ericsson.com Jan Vansteenkiste jan@vstone.eu Jarno Rajahalme jarno@ovn.org Jason Kölker jason@koelker.net Jason Wessel jason.wessel@windriver.com Jasper Capel jasper@capel.tv Jean Tourrilhes jt@hpl.hp.com Jeremy Stribling Jeroen van Bemmel jvb127@gmail.com Jesse Gross jesse@kernel.org Jian Li lijian@ooclab.com Jianbo Liu jianbol@mellanox.com Jing Ai jinga@google.com Jiri Benc jbenc@redhat.com Jochen Friedrich jochen@scram.de Joe Perches joe@perches.com Joe Stringer joe@ovn.org Jonathan Vestin jonavest@kau.se Jorge Arturo Sauma Vargas jorge.sauma@hpe.com Jun Gu jun.gu@easystack.cn Jun Nakajima jun.nakajima@intel.com JunhanYan juyan@redhat.com JunoZhu zhunatuzi@gmail.com Justin Pettit jpettit@ovn.org Kai Li likailichee@gmail.com Kaige Fu fukaige@huawei.com Keith Amidon Ken Ajiro ajiro@mxw.nes.nec.co.jp Ken Sanislo ken@intherack.com Kenneth Duda kduda@arista.com Kentaro Ebisawa ebiken.g@gmail.com Keshav Gupta keshav.gupta@ericsson.com Kevin Lo kevlo@FreeBSD.org Kevin Traynor kevin.traynor@intel.com Khem Raj raj.khem@gmail.com Kmindg G kmindg@gmail.com Kacper KamiÅ„ski lampo100@gmail.com Kris Murphy kriskend@linux.vnet.ibm.com Krishna Kondaka kkondaka@vmware.com Kyle Mestery mestery@mestery.com Kyle Simpson kyleandrew.simpson@gmail.com Kyle Upton kupton@baymicrosystems.com Lance Richardson lrichard@redhat.com Lars Kellogg-Stedman lars@redhat.com Lei Huang huang.f.lei@gmail.com Leif Madsen lmadsen@redhat.com Leo Alterman Li RongQing lirongqing@baidu.com Lian-min Wang liang-min.wang@intel.com Lilijun jerry.lilijun@huawei.com Lili Huang huanglili.huang@huawei.com Linda Sun lsun@vmware.com Lior Neudorfer lior@guardicore.com Liu Chang txfh2007@aliyun.com Lorand Jakab lojakab@cisco.com Lorenzo Bianconi lorenzo.bianconi@redhat.com Luca Giraudo Lucas Alvares Gomes lucasagomes@gmail.com Lucas Vargas Dias lucas.vdias@luizalabs.com Lucian Petrut lpetrut@cloudbasesolutions.com Luigi Rizzo rizzo@iet.unipi.it Luis E. P. l31g@hotmail.com Lukasz Rzasik lukasz.rzasik@gmail.com Madhu Challa challa@noironetworks.com Mairtin O'Loingsigh moloings@redhat.com Manohar K C manukc@gmail.com Manoj Sharma manoj.sharma@nutanix.com Marcin Mirecki mmirecki@redhat.com Mario Cabrera mario.cabrera@hpe.com Mark D. Gray mark.d.gray@redhat.com Mark Hamilton Mark Kavanagh mark.b.kavanagh81@gmail.com Mark Maglana mmaglana@gmail.com Mark Michelson mmichels@redhat.com Markos Chandras mchandras@suse.de Martin Casado casado@cs.stanford.edu Martin Fong mwfong@csl.sri.com Martin Kalcok martin.kalcok@canonical.com Martin Xu martinxu9.ovs@gmail.com Martino Fornasa mf@fornasa.it Maryam Tahhan maryam.tahhan@intel.com Matteo Croce mcroce@redhat.com Matthias May matthias.may@neratec.com Mauricio Vásquez mauricio.vasquezbernal@studenti.polito.it Max Lamprecht max.lamprecht@mail.schwarz Maxim Korezkij maxim.korezkij@mail.schwarz Maxime Coquelin maxime.coquelin@redhat.com Mehak Mahajaon Mengxin Liu mengxin@alauda.io Michael Arnaldi arnaldimichael@gmail.com Michal Weglicki michalx.weglicki@intel.com Mickey Spiegel mickeys.dev@gmail.com Miguel Angel Ajo majopela@redhat.com Mijo Safradin mijo@linux.vnet.ibm.com Mika Vaisanen mika.vaisanen@gmail.com Minoru TAKAHASHI takahashi.minoru7@gmail.com MJ Ponsonby mj.ponsonby@canonical.com Mohammad Heib mheib@redhat.com Moshe Levi moshele@mellanox.com Murphy McCauley murphy.mccauley@gmail.com Natasha Gude Neal Shrader neal@digitalocean.com Neil McKee neil.mckee@inmon.com Neil Zhu zhuj@centecnetworks.com Nimay Desai nimaydesai1@gmail.com Nithin Raju nithin@vmware.com Niti Rohilla niti.rohilla@tcs.com Nitin Katiyar nitin.katiyar@ericsson.com Naveen Yerramneni naveen.yerramneni@nutanix.com Numan Siddique nusiddiq@redhat.com Nobuhiro MIKI nmiki@yahoo-corp.jp Ofer Ben-Yacov ofer.benyacov@gmail.com Ophir Munk ophirmu@mellanox.com Or Gerlitz ogerlitz@mellanox.com Ori Shoshan ori.shoshan@guardicore.com Padmanabhan Krishnan kprad1@yahoo.com Panu Matilainen pmatilai@redhat.com Paraneetharan Chandrasekaran paraneetharanc@gmail.com Paul Boca pboca@cloudbasesolutions.com Paul Fazzone pfazzone@vmware.com Paul Ingram Paul-Emmanuel Raoul skyper@skyplabs.net Pavithra Ramesh paramesh@vmware.com Pedro Guimaraes pedro.guimaraes@canonical.com Peter Downs padowns@gmail.com Philippe Jung phil.jung@free.fr Pim van den Berg pim@nethuis.nl pritesh pritesh.kothari@cisco.com Pravin B Shelar pshelar@ovn.org Przemyslaw Szczerbik przemyslawx.szczerbik@intel.com Quentin Monnet quentin.monnet@6wind.com Qiuyu Xiao qiuyu.xiao.qyx@gmail.com Raju Subramanian Rami Rosen ramirose@gmail.com Ramu Ramamurthy ramu.ramamurthy@us.ibm.com Randall Sharo andall.sharo@navy.mil Ravi Kerur Ravi.Kerur@telekom.com Raymond Burkholder ray@oneunified.net Reid Price Remko Tronçon git@el-tramo.be Renat Nurgaliyev impleman@gmail.com Rich Lane rlane@bigswitch.com Richard Oliver richard@richard-oliver.co.uk Rishi Bamba rishi.bamba@tcs.com Rob Adams readams@readams.net Robert Ã…kerblom-Andersson Robert.nr1@gmail.com Robert Wojciechowicz robertx.wojciechowicz@intel.com Roberto Bartzen Acosta rbartzen@gmail.com Rob Hoes rob.hoes@citrix.com Robin Brämer robin.braemer@web.de Rohith Basavaraja rohith.basavaraja@gmail.com Roi Dayan roid@mellanox.com Róbert Mulik robert.mulik@ericsson.com Romain Lenglet romain.lenglet@berabera.info Roni Bar Yanai roniba@mellanox.com Rosemarie O'Riorden rosemarie@redhat.com Russell Bryant russell@ovn.org RYAN D. MOATS rmoats@us.ibm.com Ryan Goulding rgouldin@redhat.com Ryan Wilson Sairam Venugopal vsairam@vmware.com Sajjad Lateef Saloni Jain saloni.jain@tcs.com Samuel Ghinet sghinet@cloudbasesolutions.com Sanjay Sane Saurabh Mohan saurabh@cplanenetworks.com Saurabh Shah Saurabh Shrivastava saurabh.shrivastava@nuagenetworks.net Scott Cheloha scottcheloha@gmail.com Scott Lowe scott.lowe@scottlowe.org Scott Mann sdmnix@gmail.com Selvamuthukumar smkumar@merunetworks.com Sha Zhang zhangsha.zhang@huawei.com Shad Ansari shad.ansari@hpe.com Shan Wei davidshan@tencent.com Sharon Krendel thekafkaf@gmail.com Shashank Ram rams@vmware.com Shashwat Srivastava shashwat.srivastava@tcs.com Shibir-basak shibir.basak@nutanix.com Shih-Hao Li shihli@vmware.com Shu Shen shu.shen@radisys.com Simon Horman horms@ovn.org Sorin Vinturis svinturis@cloudbasesolutions.com Sragdhara Datta Chaudhuri sragdha.chaudhu@nutanix.com Steffen Gebert steffen.gebert@informatik.uni-wuerzburg.de Sten Spans sten@blinkenlights.nl Stephane A. Sezer sas@cd80.net Stephen Finucane stephen@that.guru Steve Ruan ruansx@cn.ibm.com Stuart Cardall developer@it-offshore.co.uk Sugesh Chandran sugesh.chandran@intel.com SUGYO Kazushi sugyo.org@gmail.com Surya Seetharaman suryaseetharaman.9@gmail.com Sven Haardiek sven.haardiek@uni-muenster.de Tadaaki Nagao nagao@stratosphere.co.jp Tao Liu taoliu828@163.com Terry Wilson twilson@redhat.com Tetsuo NAKAGAWA nakagawa@mxc.nes.nec.co.jp Thadeu Lima de Souza Cascardo cascardo@cascardo.eti.br Thomas F. Herbert thomasfherbert@gmail.com Thomas Goirand zigo@debian.org Thomas Graf tgraf@noironetworks.com Thomas Lacroix thomas.lacroix@citrix.com Tiago Pires tiago.pires@luizalabs.com Tim Rozet trozet@redhat.com Timo Puha timox.puha@intel.com Timothy Redaelli tredaelli@redhat.com Todd Deshane deshantm@gmail.com Tom Everman teverman@google.com Toms Atteka cpp.code.lv@gmail.com Torgny Lindberg torgny.lindberg@ericsson.com Tsvi Slonim tsvi@toroki.com Tuan Nguyen tuan.nguyen@veriksystems.com Tyler Coumbes coumbes@gmail.com Tony van der Peet tony.vanderpeet@alliedtelesis.co.nz Tonghao Zhang xiangxia.m.yue@gmail.com Valient Gough vgough@pobox.com Vanou Ishii ishii.vanou@fujitsu.com Vasyl Saienko vsaienko@mirantis.com Veda Barrenkala vedabarrenkala@gmail.com Venkata Anil Kommaddi vkommadi@redhat.com Venu Iyer venugopali@nvidia.com Vishal Deep Ajmera vishal.deep.ajmera@ericsson.com Vivien Bernet-Rollande vbr@soprive.net Vladislav Odintsov odivlad@gmail.com wangqianyu wang.qianyu@zte.com.cn wangchuanlei wangchuanlei@inspur.com Wang Sheng-Hui shhuiw@gmail.com Wang Zhike wangzhike@jd.com Wei Li liw@yusur.tech Wei Yongjun yjwei@cn.fujitsu.com Wenyu Zhang wenyuz@vmware.com William Fulton William Tu u9012063@gmail.com Xiao Liang shaw.leon@gmail.com Xie Liu liushyshy@gmail.com xu rong xu.rong@zte.com.cn YAMAMOTO Takashi yamamoto@midokura.com Yasuhito Takamiya yasuhito@gmail.com Yi Li yili@winhong.com Yi-Hung Wei yihung.wei@gmail.com Yifeng Sun pkusunyifeng@gmail.com Yin Lin linyi@vmware.com Yu Zhiguo yuzg@cn.fujitsu.com Yuanhan Liu yuanhan.liu@linux.intel.com Yunjian Wang wangyunjian@huawei.com Yousong Zhou yszhou4tech@gmail.com Zak Whittington zwhitt.vmware@gmail.com ZhengLingyun konghuarukhr@163.com Zoltán Balogh zoltan.balogh.eth@gmail.com Zoltan Kiss zoltan.kiss@citrix.com Zongkai LI zealokii@gmail.com Zhi Yong Wu zwu.kernel@gmail.com Zang MingJie zealot0630@gmail.com Zhen Wang zhewang@nvidia.com Zhenyu Gao sysugaozhenyu@gmail.com ZhiPeng Lu luzhipeng@uniudc.com Zhou Yangchao 1028519445@qq.com aginwala amginwal@gmail.com parameswaran krishnamurthy parkrish@gmail.com solomon liwei.solomon@gmail.com wenxu wenxu@ucloud.cn wisd0me ak47izatool@gmail.com Xavier Simonart xsimonar@redhat.com xieyanker xjsisnice@gmail.com xushengping shengping.xu@huawei.com yinpeijun yinpeijun@huawei.com zangchuanqiang zangchuanqiang@huawei.com zhang yanxian zhangyanxian@pmlabs.com.cn zhangqiang45 zhangqiang45@lenovo.com zhaojingjing zhao.jingjing1@zte.com.cn zhongbaisong zhongbaisong@huawei.com zhaozhanxu zhaozhanxu@163.com ================================== =============================================== The following additional people are mentioned in commit logs as having provided helpful bug reports or suggestions. =============================== =============================================== Name Email =============================== =============================================== Aaron M. Ucko ucko@debian.org Abhinav Singhal Abhinav.Singhal@spirent.com Adam Heath doogie@brainfood.com Ahmed Bilal numan252@gmail.com Alan Kayahan hsykay@gmail.com Alan Shieh Alban Browaeys prahal@yahoo.com Alex Yip Alexey I. Froloff raorn@altlinux.org Amar Padmanabhan Amey Bhide Amre Shakimov ashakimov@vmware.com André Ruß andre.russ@hybris.com Andreas Beckmann debian@abeckmann.de Andrei Andone andrei.andone@softvision.ro Andrey Korolyov andrey@xdel.ru Anil Jangam anilj.mailing@gmail.com Anshuman Manral anshuman.manral@outlook.com Anton Matsiuk anton.matsiuk@gmail.com Anup Khadka khadka.py@gmail.com Anuprem Chalvadi achalvadi@vmware.com Ariel Tubaltsev atubaltsev@vmware.com Arkajit Ghosh arkajit.ghosh@tcs.com Atzm Watanabe atzm@stratosphere.co.jp Aurélien Poulain aurepoulain@viacesi.fr Bastian Blank waldi@debian.org Ben Basler Bhargava Shastry bshastry@sec.t-labs.tu-berlin.de Bob Ball bob.ball@citrix.com Brad Hall Brad Cowie brad@wand.net.nz Brailey Josh josh@faucet.nz Brandon Heller brandonh@stanford.edu Brendan Kelley Brent Salisbury brent.salisbury@gmail.com Brian Field Brian_Field@cable.comcast.com Bryan Fulton Bryan Osoro Cedric Hobbs Chris Hydon chydon@aristanetworks.com Christian Stigen Larsen cslarsen@gmail.com Christopher Paggen cpaggen@cisco.com Chunhe Li lichunhe@huawei.com Daniel Badea daniel.badea@windriver.com Daniel Ding danieldin186@gmail.com Darragh O'Reilly darragh.oreilly@hpe.com Dave Walker DaveWalker@ubuntu.com David Evans davidjoshuaevans@gmail.com David Palma palma@onesource.pt David van Moolenbroek dvmoolenbroek@aimvalley.nl Derek Cormier derek.cormier@lab.ntt.co.jp Dhaval Badiani dbadiani@vmware.com DK Moon Ding Zhi zhi.ding@6wind.com Dong Jun dongj@dtdream.com Dustin Spinhirne dspinhirne@vmware.com Edwin Chiu echiu@vmware.com Eivind Bulie Haanaes Enas Ahmad enas.ahmad@kaust.edu.sa Eric Lopez Frido Roose fr.roose@gmail.com Gaetano Catalli gaetano.catalli@gmail.com Gavin Remaley gavin_remaley@selinc.com Georg Schmuecking georg.schmuecking@ericsson.com George Shuklin amarao@desunote.ru Gerald Rogers gerald.rogers@intel.com Ghanem Bahri bahri.ghanem@gmail.com Giuseppe de Candia giuseppe.decandia@gmail.com Gordon Good ggood@vmware.com Greg Dahlman gdahlman@hotmail.com Greg Rose gvrose8192@gmail.com Gregor Schaffrath grsch@net.t-labs.tu-berlin.de Gregory Smith gasmith@nutanix.com Guolin Yang gyang@vmware.com Gur Stavi gstavi@mrv.com Harish Kanakaraju hkanakaraju@vmware.com Hari Sasank Bhamidipalli hbhamidi@cisco.com Hassan Khan hassan.khan@seecs.edu.pk Hector Oron hector.oron@gmail.com Hemanth Kumar Mantri mantri@nutanix.com Henrik Amren Hiroshi Tanaka Hiroshi Miyata miyahiro.dazu@gmail.com Hsin-Yi Shen shenh@vmware.com Hui Xiang xianghuir@gmail.com Hyojoon Kim joonk@gatech.edu Igor Ganichev Igor Sever igor@xorops.com Jacob Cherkas cherkasj@vmware.com Jacob Tanenbaum jtanenba@redhat.com Jad Naous jnaous@gmail.com Jamal Hadi Salim hadi@cyberus.ca James Schmidt jschmidt@vmware.com Jan Medved jmedved@juniper.net Janis Hamme janis.hamme@student.kit.edu Jari Sundell sundell.software@gmail.com Javier Albornoz javier.albornoz@hpe.com Jed Daniels openvswitch@jeddaniels.com Jeff Merrick jmerrick@vmware.com Jeongkeun Lee jklee@hp.com Jian Qiu swordqiu@gmail.com Joan Cirer joan@ev0.net John Darrington john@darrington.wattle.id.au John Galgay john@galgay.net John Hurley john.hurley@netronome.com John Reumann nofutznetworks@gmail.com Karthik Sundaravel ksundara@redhat.com Kashyap Thimmaraju kashyap.thimmaraju@sec.t-labs.tu-berlin.de Keith Holleman hollemanietf@gmail.com Kevin Lin kevinlin@berkeley.edu K è¯ k940545@hotmail.com Kevin Mancuso kevin.mancuso@rackspace.com Kiran Shanbhog kiran@vmware.com Kirill Kabardin Kirkland Spector kspector@salesforce.com Koichi Yagishita yagishita.koichi@jrc.co.jp Konstantin Khorenko khorenko@openvz.org Kris zhang zhang.kris@gmail.com Krishna Miriyala miriyalak@vmware.com Krishna Mohan Elluru elluru.kri.mohan@hpe.com László Sürü laszlo.suru@ericsson.com Len Gao leng@vmware.com Logan Rosen logatronico@gmail.com Luca Falavigna dktrkranz@debian.org Luiz Henrique Ozaki luiz.ozaki@gmail.com Manpreet Singh er.manpreet25@gmail.com Marco d'Itri md@Linux.IT Martin Vizvary vizvary@ics.muni.cz Marvin Pascual marvin@pascual.com.ph Maxime Brun m.brun@alphalink.fr Madhu Venugopal mavenugo@gmail.com Michael A. Collins mike.a.collins@ark-net.org Michael Ben-Ami mbenami@digitalocean.com Michael Hu humichael@vmware.com Michael J. Smalley michaeljsmalley@gmail.com Michael Mao Michael Shigorin mike@osdn.org.ua Michael Stapelberg stapelberg@debian.org Mihir Gangar gangarm@vmware.com Mike Bursell mike.bursell@citrix.com Mike Kruze Mike Qing mqing@vmware.com Min Chen ustcer.tonychan@gmail.com Mikael Doverhag Mircea Ulinic ping@mirceaulinic.net Mrinmoy Das mrdas@ixiacom.com Muhammad Shahbaz mshahbaz@cs.princeton.edu Murali R muralirdev@gmail.com Nagi Reddy Jonnala njonnala@Brocade.com Niels van Adrichem N.L.M.vanAdrichem@tudelft.nl Niklas Andersson Oscar Wilde xdxiaobin@gmail.com Pankaj Thakkar pthakkar@vmware.com Pasi Kärkkäinen pasik@iki.fi Patrik Andersson R patrik.r.andersson@ericsson.com Patryk Diak pdiak@redhat.com Paul Greenberg Paulo Cravero pcravero@as2594.net Paulo Guilherme da Silva guilherme.paulo@luizalabs.com Pawan Shukla shuklap@vmware.com Periyasamy Palanisamy periyasamy.palanisamy@ericsson.com Peter Amidon peter@picnicpark.org Peter Balland Peter Phaal peter.phaal@inmon.com Prabina Pattnaik Prabina.Pattnaik@nechclst.in Pratap Reddy Ralf Heiringhoff ralf@frosty-geek.net Ram Jothikumar Ramana Reddy gtvrreddy@gmail.com Ray Li rayli1107@gmail.com Richard Theis rtheis@us.ibm.com RishiRaj Maulick rishi.raj2509@gmail.com Rob Sherwood rob.sherwood@bigswitch.com Robert Strickler anomalyst@gmail.com Roger Leigh rleigh@codelibre.net Rogério Vinhal Nunes Roman Sokolkov rsokolkov@gmail.com Ronaldo A. Ferreira ronaldof@CS.Princeton.EDU Ronny L. Bull bullrl@clarkson.edu Sandeep Kumar sandeep.kumar16@tcs.com Sander Eikelenboom linux@eikelenboom.it Saul St. John sstjohn@cs.wisc.edu Scott Hendricks Sean Brady sbrady@gtfservices.com Sebastian Andrzej Siewior sebastian@breakpoint.cc Sébastien RICCIO sr@swisscenter.com Shweta Seth shwseth@cisco.com Simon Jouet simon.jouet@gmail.com Spiro Kourtessis spiro@vmware.com Sridhar Samudrala samudrala.sridhar@gmail.com Srini Seetharaman seethara@stanford.edu Sabyasachi Sengupta Sabyasachi.Sengupta@alcatel-lucent.com Salvatore Cambria salvatore.cambria@citrix.com Soner Sevinc sevincs@vmware.com Stepan Andrushko stepanx.andrushko@intel.com Stephen Hemminger shemminger@vyatta.com Stuart Cardall developer@it-offshore.co.uk Suganya Ramachandran suganyar@vmware.com Sundar Nadathur undar.nadathur@intel.com Taekho Nam thnam@smartx.kr Takayuki HAMA t-hama@cb.jp.nec.com Teemu Koponen Thomas Morin thomas.morin@orange.com Timothy Chen Torbjorn Tornkvist kruskakli@gmail.com Tulio Ribeiro tribeiro@lasige.di.fc.ul.pt Tytus Kurek Tytus.Kurek@pega.com Valentin Bud valentin@hackaserver.com Vasiliy Tolstov v.tolstov@selfip.ru Vasu Dasari vdasari@gmail.com Vinllen Chen cvinllen@gmail.com Vishal Swarankar vishal.swarnkar@gmail.com Vjekoslav Brajkovic balkan@cs.washington.edu Voravit T. voravit@kth.se Yeming Zhao zhaoyeming@gmail.com Yi Ba yby.developer@yahoo.com Ying Chen yingchen@vmware.com Yongqiang Liu liuyq7809@gmail.com ZHANG Zhiming zhangzhiming@yunshan.net.cn Zhangguanghui zhang.guanghui@h3c.com Ziyou Wang ziyouw@vmware.com ankur dwivedi ankurengg2003@gmail.com chen zhang 3zhangchen9211@gmail.com james hopper jameshopper@email.com kk yap yapkke@stanford.edu likunyun kunyunli@hotmail.com meishengxin meishengxin@huawei.com neeraj mehta mehtaneeraj07@gmail.com rahim entezari rahim.entezari@gmail.com shaoke xi xishaoke.xsk@gmail.com shivani dommeti shivani.dommeti@gmail.com weizj 34965317@qq.com 俊 èµµ zhaojun12@outlook.com 冯全树(Crab) fqs888@126.com 张东亚 fortitude.zhang@gmail.com 胡é–飞 hujingfei914@msn.com 张伟 zhangwqh@126.com 张强 zhangqiang@meizu.com =============================== =============================================== Thanks to all Open vSwitch and OVN contributors. If you are not listed above but believe that you should be, please write to dev@openvswitch.org. ovn-25.09.0~git20250813.23884f5/CONTRIBUTING.rst000066400000000000000000000024511504532661100176100ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========================================== Contributing to Open Virtual Network (OVN) ========================================== As an open source project, we welcome contributions of any kind. These can range from bug reports and code reviews, to signficant code or documentation features. Extensive guidelines are provided in the docs at ``Documentation/internals/contributing``, or `online `__. ovn-25.09.0~git20250813.23884f5/Documentation/000077500000000000000000000000001504532661100177565ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/_static/000077500000000000000000000000001504532661100214045ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/_static/logo.png000066400000000000000000000246051504532661100230610ustar00rootroot00000000000000‰PNG  IHDRÈÈ­X®žgAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ< pHYsgŸÒRYiTXtXML:com.adobe.xmp 1 LÂ'Y'–IDATxí ”Žÿ³2À Œ ‚kT j jN⾞‡DEÍ3‰Ñ—.ϼwò\b|õÅxB4ñ¸ž§Æ¿‰‰FP•@0nD(¢â†ŒÀ ìýÿ} ~MÏåÞ™»Ì¹}oÕšî®®®úÕ·~ßÚ»ºLLUê4Fíáj§¨¯vµÔzã(6jB–¨}Sí"µóÕ.+++kÑchÊ8SR¨{™‚:½Qû¿jP.Ô'B¥W‡‘zó‡jg¨ª6¥Q¿)ïùBF@•¿+ñÖêÍÕ^«þVãÑjjŽëÔž¥¶Vm”aˆ£›ôQo<…@‚'êzƒJ¯Ú«¨I*Õ3Í'šUÔ£Cm¹ÚÐX€£½½]6mÚ$­­­ÒÖÖæüØ}ŽÞx tÕô²¼¼\*++¥_¿~Î&òa r£ûp.¼®ÏÿŠŽÇ½xX-s4<ú€^n6D¶fÍyýõ×åÿø‡¼ù曲hÑ"ùôÓOiÌŸ?z #¤Øwß}e„ 2yòdÙo¿ýd—]v‘RŽ9–j:¦C õäjµ4³ì¦žn5MMM²lÙ2¹å–[ä®»îrÍ,S]]-[=ú3@"@‹}ÅŒ3FfÍš%'t’ì°Ãɤ5ÔëÍÿ‚ wéÉtµÕÚM=Ýlä¾ûüä'òî»ïº*Ê"ãhçæß=…†µ‰YºtÎ8ã ¹ì²Ë\íB,bŒêö0 ¾Pm³ÚmŒ2/¸çž{‚Ñ£GóP ÕR 5cÂÎâæ­Ç ÐuÀôU‰TUUýû÷wz{â‰'«V­ÚFï·8À‰…¤QmÇÇðÐÑÑüýï¦L™â8p '…/Š¢@Ô»# ľꪫ‚uëÖ…z9¤“úÆ7¾áÑŽŽ'‡'GQÃj;jj®Ÿyæ™@Ge;ñÀ.:5¾ÔsØçwäÞ{Ö±¯Žß×pHøÅ‚}%‰KÎ#<"ôµ1J w´b7›››åµ×^sÄ`”ŠN7bB]7}þù祥¥Ó¬0©b®x† bÙ}ô´ŒÝbn¯¾žQÝÍ-¨hÚ’„Yòýë_á=E„aH Ò1³É9nù2Ñøˆ3ßñe›äÄ"c!Ëié‹Êç|D¯ÁóöÛo»Õ!–F;VÚIôȃëׯwN=AŽhæÃZˆAa­H3®§šr„KÆa¢áZf’&Ú =‘6I–ÿÀÅdŠâB¦%“?Ëhzì±Ä|4 {#Á‡ø0è ²äš<ì˜ 6¸.ç¸>&)AÜúgJ]»eA“hkû™Ræ'Ó£)–…}>6«¸F†¾0¤"Xa•!‘Ô¤ ·¾$t&ùˆƒm.òZMš,£˜Øä+óJ”5/ÔF;í´“L›6Í­…ÙgŸ}dðàÁ®Zûç?ÿéÚ€Ï>û¬c­Î·8ÿÙ€»ÝvÛ9…ciÌG!“&M’qãÆÉÞ{ï-¸×âÅ‹å¯ý«¬\¹ÒÉÀ€KzÓÔÔÔ¸ :”.»ï¾»rÈ!NNÖ Í[d}õÕW\tbKÀ%ZÊõ¦¼´¶¶V>ÿüsÑIc9øàƒÝÚ&òqøðᢓmN^ú­O>ù¤+•É‹lä…ˆÄEþ3²tÐAÉþûïïð!/! ëÁgáÂ…Nwˆ Bnܸ±çaQAB£,tçº1PscĪäY+³Ö=;sæÌ@3X»vm  ª”nÜYäæ[>þøãàüc À;ÿÆ Ë8ΡC‡ºgt­MðÀ~ø¡ »±±ÑÅEœÄ K–, .¾øâ0æyÙ^±JŽ0ž /¼0ÐÌv2i!°rAKÇ™U]t2;v¬{F!»ï-yµ$”´.~]¿¨Rv’W3°|Do” .tþ ”‘¼JŽ@Éáž%On¿ýöàý÷ßwX(Y6J—Ú©´ßüèG?rþÁƒ•™à¢µx8aøàƒ:ü!€ñ€s˜»‘+A ‚î±ÇÁÝwß|òÉ'a©NzùòåÁå—_îž2dHÚ““–ßùÎwœÂA†î Dùío|ñ‹_tñe[d’!FŽ<0@ñ‘¡;ƒBèBѰEi3‰7[¿Äcy© UƒÕ«Ww'n@>¢¸W_}µ“EOG^”Õ ªo}ë[®@…xÝ –§Ÿ~:8úè£]|` ÑÒIsŸÄIIþØc¹ÒÐ „¸ÙuÔL d%dNW‰åžeàôéÓ;­«I¶¹™<I›[ÁÔ©SCpÓ6?,Õá9jÉçž{.,­¢8˜\&g -+<(ºÂ%ùŸA©-Ž»îºË•â‰òÙu²4è«Á5×\*jW$!+ä¾ýíoï½÷^t2,Ý ¥6GƒcŽ9ÆÅGÍ•˜žd×½N@°’p´ÝïÍè0å 'Q?K—. ´íéiH–@kÂQSýío CŒ†:&œ˜Jè_üâ¡2X˜ÉâËÖ \hñü­·Þ'ÆdH­Ó%~ÌŸ¶»}ŸÁ…c ©«çPXSèóÏ??$‡ÉÑIÀ„‹¨¼|ðA@ÁE\œF¸Ä¸¹‡²ÖÕչ˂L7>üã—¦5aÓÔJ'{• $ÞJI˜¼bÅ —Ît™mqš?¤e–]s$qæ>wîÜ€6*&›øè¯œyæ™.>Ò*#£ñgrn¸|ík_ k¹lä}õÀÉ™I4Yñk­š‚:‰fÙ“ñ‘’]g©}aÉÉlM̨<`mµÇüã€&&|¨eÏ9çW:µH:I:Q¨ ÈØ¨²Š6YÜs_þò—ݨU¦(XnôB3HƒQ a'ÜÞÛqÇåØcu£<ø!ŒLÍöÛo/_ùÊWœÌÚAçf2 '™äÑZÐÝR‚ˆ@$óÖ¥[Fç0ª@á~—gxS•&2e´j×]wu!¨ÎfþÉ#ÞâÓA÷,8$æ׿¦«¨b;¿æ–I¤J4! qgFb|=J-1dÏ=÷”½öÚ+œèÊVHÀäí/ `'†c×Ú¼rÂæÏ=æ? 0‰kçwvOšB§L—Þ,<1,jaGÝ» á&…‡–ìnØeîiC˜Ì3 l`¢ME¦òšž7’¡ænrî˜#F¸c¦d´0£:C@æîÍò_!Ìœ†ùJ S„,år%ÀĉÝã‰À’pJP ï[&:‡ ÿYIÑÓÇä*{T„h&1ƒ¬™*@4<ž×A§Ä„ ?ê/ÛsÃräÈ‘nî!W,¢Q1Å1jŸù j×\â2LiQ`h]ô6=FK8%$A8: Hwç–(€eRJÛï.œhi‰ÀàÇâî.ì®îO.Õ{Wa›¬`“«+‘ ËðÊ5\{Þ°dò l0v?Ó#áA6t“˜ÈOaGeqgGÔ?òRhÒÜÆõ“ÉyÄ”€ÙS÷p2d“yF*ÂÓQ¡O` ZÂðc`âÇâ¶ûÙ)ÅR½MxÑg,£À&WCmª“ga0†Wèã‰a‰¬:ä6² –ð>úè£P'¬æ'»82 Òp¡]­³ðîqpÊALA!"MŒ¹¹‹4þáŸ|£`ïÙ¢“6Ë3jk†š[ÔowçúÏþ³óFÜÙ„±MHhpwžíZ,mö„“L졉uáY¸aDIN¢~XÀ7~üx7ᣤsG|›£–<ÎM7 ´ÙN.EÃJU'™˜ígá#¿…™,¾lÝW;è.Žo¼1£kéaÒî _ø‚ 'Ù¤[¶ò%>§ÊâpöÙg,‰Êá.ºøgò*¹ÂåL>nb\\kÆ7þü0d 'tHrb~”|î¡àÂgÁc:ùH¾˜~¥Z¬Øc5ˆ&´S‰öðÃË_þò7š`¥¦oÛÜÍ’Sn»í6×L£ª·Òw›‡Ô{ÔZ”ü7ÜpC؇ ,ÂLŸ¹á‡çiFÜÿý.x溊/™ é¸i&†á²AÀ+¯¼â®»“3*+¥#›hè‚NÑYôpR6ø3õC¼È¬ $º/š<ñÄnÃòÈäJ ×ÜñÇÒx{Ôv?ñ9î±Ä£‹[Ã}:ø˜p±|DîËG:4ÆÆlkMŸc°6}Ü‘õT¬IgÕ*qSâühËòeÖ.iâ]8n²#~lYÁ÷¿ÿý€u\ N˜¦T'ªpn1åQGÊœN|ÉdHǰ­´:òÈ#ƒ?üáᲊT2âNZX¶.ÔB„“N阎LÝù¡„%/uíWKgU¶6mÜrjJj ÒL8éÄeéâUjKmjw»Ç«,þœ1c†‹ƒøÒÍGä²âJÔtäIå‡8¬ðØm·ÝÜj×wÞyǽOÅ…æ²óNÈSO=œ|òÉNNžÍ—Trdâï‚ .pïÒ° |³|„\Ó¤fu4;š²GŸï.^üÚs¼ôÐCÚ:ß“1Eµ|d ÝÏþó@'”C|2ÉGâëŽ î³R*¸3*€kê°‹»2RæÍ›çF4T ó’Ñ‘& K 3¥,µ` –‰(:€ª n”ƒ:…ªÎ?¬LŒ&Ö5·ˆ‰¢8ÀM>í®oìaUá\ó„#ÿ?ýéO®Ú×¶¼“‘´÷†Ñ to"æ¸ãŽso<"#3íLV‚ÉÛº‰GÞ€U×DÉ—žHM]ÓËG&+‘—µe 3R…Ì4,Xµ¼Ñ|Ôþ–[5À$"–eL4ÇØHGò’A šØ !ƒi&ùH\èaj â6´Fg;½•¹6±4`ÇhŽtÀ¨j£n©Î©9¬„Må§+wJ„tß*#ž|vt»’“{`b¥ew~IS.¸t~:÷)iÉŸtüÒIÎEÞLòy+“šÃÒ@<ÝÕ y}']q%L¥ÆPÐ\çRž’’I ‡v™ÍV¶òXVF îÖûPšP35âCJ“aa+ųŠ,LJ YX~‚lÈN)¼ÈIAmƒŒÌ å‚KŽ¢ºÇ)eÉ3j8dC^ܰ‰ù¶¹ÈKØè80߃‰æ#ñqøäËä N‚Ù¸ G°œ£$–ù¹‡pŊƇ €É±§âŠÆ›Í9 ÇèrbÉtŽÈnrЬ¤™˜§H”7ùH|„‹%>t|À¬7ó±WBb1d6 ÄæÛ–L-t'YÁ²·å%¾ÞÒ›D]éÑyÄÀýµG îx‚Ä=½üyEÀ$¯ðúÀ㎀'HÜsÐËŸW.J‘ôK¼rüñÇ»]ZVêþU?ûÙÏÜ6¤äù'’Aø¾»mÌœ9S.½ôRG¶†ñ¦÷ ¡@Âb†*º ©vØarýõ×»ÍûÈÛˆ®÷%Ì,Æx÷ 4­t­ú¿ì²Ëdÿý÷wû4áf63H¼ï\0Ü-_øöãi§&çž{® š}ËâR£Çš €L‰EP¿•.lU‰!cp7ëý¿^CÀpçˆ!?ØîÔSOuŸÛf/0Râ`bMkÏêí¢<»L0rÄüR“Q7 —óÎ;Ï%›f–¨qˆ-A¢àÒ¬²-* ìR•¼¢àb^dòäÉ! Ñ<  ì$¶¡yÅ"fÒ¤I|Îã:r–ªáã?4¯È»8ôCbK+•-áCõ~Ô*”£Y|øá‡»~c ³X•`DÄvH‡Š”¶”¢®®®Ó@J!#[‚DACI•·”ÏÉ«8åWQ¤”Χ=¿x‚ä_zÌð‰yzñó‹€'H~ñõ¡ÇO˜g ?¿x‚ä_zÌð‰yzñó‹€'H~ñõ¡ÇO˜g ?¿x‚ä_zÌð‰yzñó‹€'H~ñõ¡ÇO˜g ?¿x‚äß‚ ]·³p¿‚®À„*Šm Ó‚Gœ¼Œ…" ¯A %'zI޶Ž6ù¤áihiè¥ã¯AâiKo»½4¶4ÊM»I¶«ÜNΞ|¶Œ4RÊË|9™ HL*dŠØ}}Óz¹êå«ä¢Ç/’ï-¦¶¦"NmnIóÉ ¿X>íú -"¿[ö;9ñÿ(w/¾[>nü8L ]xo6#à R‚š`$ƒdͺ52{þl¹üÏ—ËÒ5K¥C¾¿U)jüÈy¥6¡ƒ_ªÆbõPλ’=ŠáC»´K“þjËkåúwdÖó³dÉKä܃Ε}wÚWV t(‘ÆRk~ù¤‡‚â¸=Ÿœ ¹«Â:Û²Ó:CºÉ”åoÐ_MyTlª;߸SNþíÉò«…¿’6|¤wK¨†¯Az€ L¾mhÞ vp·(b4Ød Éýd~»ª0áùæÓmþ»p#5Ö6ñD ™TYQ) ­ ÒÚ±yOcWë%„º)Ø$•å•2DŸ}ö™\òô%òôª§å‡_ú¡L1Ij*ãñÙ‚„de}é ’5t[\µn•Üð òáÆ¥E§Ü(+¥µ+±•4z¶ùG Îõ–£ó§qó3w+å£G÷-Êþȳe¸lv‹>Oh¾ùW¤©µÉVi… múKFú%ëôW]Q-ƒ‚A2où^"7¾|£k²Ìùê qR&:Სlƒ ¯.WM½JfNž)Cûu¨PëÐ$K$U–Åò1¿Ô$ÍlCñÍÐÑ}ì­ÇdæïgÊÿ-ù?éh+ÌQ+“7ñh ߨÑ(mÕmrÊž§È}'Ü'ß<à›[ɡ酥n| ’†X­À:¤•õ+å¦o’ÛÞ¸Mª›ªE×îÅÎÙG-çL>GÎ;ð<1hD§šÂH»Äõ°Àž iв0¸èƒErÍs×È+Ÿšö·ü›¥í¦piU^š>bÔòƒƒ ‡îv¨ î7ØÉeAAY Bx‚¤Èˆ¨²|²ñùÝ’ßÉ î”Ÿ.쵕éëªÚFÙÒZâ5ÚS÷9Uf2ËíË YÌøZÃØzÜŠÎV·’>3b ,¬¯Z¾v¹Üúâ­rÛ?oÑýÔú—ëp¨þ K0âbLù™¯9hÔARUQØkÆ WOHN9pZÛ´VžZþ”Ü»ð^y|õã,²räàuÚ¨?{7Œ«U¢}ÛB«dT6OËµîž [02¥§¯±|Ír¹cÑrók7‹lÜLŒ¶ò6i ’ï‚Îh5U˜Wèd¢détÃ_Ä’'ˆƒ&Èú–õ2Å|9éÙ“D>Ô1HÊ*ˤ!hH:ûlµÆ¦¶M²¦q«=x™Hƒ MWý”.ïm©‘€ô$•ÿTîö¬ÉIl4¤ÿ·¥Ý÷ÇÔ”-9‚ðFݼwæÉO_ø©<õÁSnø–ÒUß›ËIi ]áL>ú$`@ãM÷$ŒIvÿ@\}˜‚P{,]»Tžú\ɡ݌úchÖîÇ5}ÝÉmé£iißò˜îÒ—¯û%CëðfÜÙÏ–y'Ï“¯ýº4Õ4ɦöMR«¿8ÍŒgªQ‚00a×™†SjþK®‰Å¤ÞàšÁng޽vØK&¿2Yn_|»û²’Û¶Gû"4·25lÉYÈÆÉ§yÒæj:éÞt‹@ÉD(=©Qv®ÝY.œz¡LÜq¢Ü¾àvytÕ£n(”>I¦P3*ds*Ý¢Þ\¡œ ‰É>^¾I/J’ ÖÜ¢ÚêZ·+ÉÄ&Ê„—'Èu¯\'íMínÞ ÝQ-f§;Êu°‹aÖô²#¾áumeP©ÔðµGÚ@—$A¢èP’ÒIg—ÀLûŒÙaŒœÿüù²qÝFé×ÑÏ-kg&:™±c° rôžGË€êI—¤${¶·Ý•™yVóRØÚ±Þ–#nñ•CdHùi-k•ÁưýnDàëK4Õâ²7Vbšýuj {è%µÜy½ƒâïT»“œ;å\Y8c¡œ>þtù¼êsilk”úK±¢™fµ íûBÿå¼" Ü$E†¢äÔ SFM‘9ÇΑ¹_+‡Ž8Ô}Kœm9Ùž3j¬6Qné_aÿ¢rûó®ðI*I0#jGÈ7§|Sþç„ÿ‘Sö:E«ÝÂ?¾—áMq#à ÒEþZ­@³‰N-ïrßtìMòSÿCÆ+ëƒõnM“ùë"(+¦x‚¤‘qŒüP›@„݆辵Ӯ”›»Y¦ž¦/xë'Çuø44~‚:„¢Nü(Vš¹­%è›|õ _•=¶ßCæ.š»ù³dïfxS4x‚d™•L´ñ1™ÿ>â¿åÓÆO]‡ž ¢DÊ2hÿX!à ’cf ê7HjûÕzbäˆc¡>îû 9æŒõMr Æ?^ x‚ä˜1¾I•#€þ¸'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯oðé[ü}쎀'Hg¯o( ‚°©‚7ñA Nù{‚°%O[[[|´£Ä%[~Å– Y·n¼ÿþûž$1!ßn_±b…TUU¹Ï0X>ªø±%@WVnÞsâ7Þææf‡q¡^¨ŠÐ[rµ¶¶Ê¢E‹¤ÿþBº‰-A ®Á¼ù曾)pM³~Ç{ï½ç$­¨¨ˆÅ‡|bM+žyæYµj•Þ2¢Àõ¥¤Ä³Z}Æ òä“Oº´“wæ^È`Ä– €ÚÞÞîڲ˖-“[o½UêëëÖð Y1zJ6òÁ ­W_}UæÌ™ãjþ¦¦¦XäQ¬7Ž|H²ÝvÛÉwÜ!‡v˜œpÂ îš ö$é)5Ï.ˆ¥¶ †¿óÎ;Ý  ùEmk‚0àoܸQ(gžy¦ÜxãrÆgȰa人:yP´2’7 ²páB¹å–[ä±ÇssÈ—Â+öA»ldÀ€2{ölyôÑGå’K.‘8À‡!E«æ‹V aV[P«3ZµråJùýï/×_½“®¶¶Ö¦DM[„¢ ©5’P}/X°@¦OŸ.Œ”L:U&L˜ dŽ'IÚz‘•Gð…o¿ý¶¼öÚkòî»ïºpìšÂY…Û— A’P}3?B­Af½øâ‹Îö%È¥7Cñä Í­8š¢"@Ûb1ÅæJâ˜9q–™|€Zqéo$ûèb‰$s¬ÔòM+C¥wŽq&D"BEKhB‹)âéòçùG Ö…ù‡ÇÇPêx‚”ºøôw‰€'H—ðø›¥Ž€'H©k€O—x‚t ¿Yêx‚”ºøôw‰€'H—ðø›¥Ž€'H©k€O—x‚t ¿Yêx‚”ºøôw‰€'H—ðø›¥Ž€'H©k€O¿C Õz½”ñ¯«zÍ)%Ðw[õmGÒŸ” ¼è²ë®»†øDý‰G æ ×¼Œ=z´{É.1II ›xMÃ;ž ‰°ùëb@€—éÐï=öØCvÞyg§ç‰M­N1"ôë×OöÙg‡'H1¨‚OC2ìmÓqãÆ¥Ü§A,^U;v¬³ÄöÀµûþèˆ;Ã*„£Ž:Jjjj’'I«”¤F7ƒ|ðÁ`èСèfÃl§î­Ç ö:€>ë.7.§žzj°zõê¤À‘ê·1Zk87ý´@pÅW„€@÷DñEu@kŒ@[C!9´¼ôÒKéû6DPÞIߨ¶¿Úð3MVõ°ÇÔyççö¼ýå/)ì§JsËš\4¿4 }Ô@a"€.›E––·yÝÁ,\pLœ81lj%¤Åv/T%oNÆs[³fM0wîÜ`Ò¤I¾öðM¬Xë€NaguV Û¡JSñdG8±°LÿÝ¥L™®v ZÖ$zjvËûÍo~#‹/v»æ±!±íhzô'C`ûí·—]vÙEÆŒ#Gy¤Ûà\ûÖ©öL3° äÃäB=¹ZmZ»©§ÛšTl )ø¢asb c[ÏÞÅ#PÐ`Ž£®®Îu ˜ÂÀvaŒ|Kã¿èƒÌWû‰ZÒ¥ahŒ=nÍì°ÃáælææBCÀúÌÊ'æC¥jÿWí5j‡ªeÕ¤ó#êÞ©¶€0Xo<…Ž€µrl*…¼¦ûŸé}8±´\hÕ“Ô>¤¶A-O5cVO·è&¢­ø3@ `z›DÓsŽè>€ À ·õ¨žÔ+îUGÌ µÔ$ÞxJè ÔZMðƒj¯…$ÞÝTrè5ýõ€~Èij¿§v¸Z>ÑTµÅFR'o<±F€ƒÖ¶E-}šUÔTŽÛ(½Þ€cÔ®vŠÚñj÷Q;@­7bA€ ò%jßT»Hí|µË”%4ÿÀ­S1•;½¹IEND®B`‚ovn-25.09.0~git20250813.23884f5/Documentation/automake.mk000066400000000000000000000146101504532661100221170ustar00rootroot00000000000000DOC_SOURCE = \ Documentation/group-selection-method-property.txt \ Documentation/_static/logo.png \ Documentation/conf.py \ Documentation/index.rst \ Documentation/contents.rst \ Documentation/intro/index.rst \ Documentation/intro/install/index.rst \ Documentation/intro/install/debian.rst \ Documentation/intro/install/documentation.rst \ Documentation/intro/install/distributions.rst \ Documentation/intro/install/fedora.rst \ Documentation/intro/install/general.rst \ Documentation/intro/install/ovn-upgrades.rst \ Documentation/intro/install/windows.rst \ Documentation/tutorials/index.rst \ Documentation/tutorials/ovn-openstack.rst \ Documentation/tutorials/ovn-sandbox.rst \ Documentation/tutorials/ovn-ipsec.rst \ Documentation/tutorials/ovn-ovsdb-relay.rst \ Documentation/tutorials/images/ovsdb-relay-1.png \ Documentation/tutorials/images/ovsdb-relay-2.png \ Documentation/tutorials/images/ovsdb-relay-3.png \ Documentation/tutorials/ovn-rbac.rst \ Documentation/tutorials/ovn-interconnection.rst \ Documentation/topics/index.rst \ Documentation/topics/testing.rst \ Documentation/topics/high-availability.rst \ Documentation/topics/integration.rst \ Documentation/topics/ovn-news-2.8.rst \ Documentation/topics/role-based-access-control.rst \ Documentation/topics/vif-plug-providers/index.rst \ Documentation/topics/vif-plug-providers/vif-plug-providers.rst \ Documentation/howto/index.rst \ Documentation/howto/docker.rst \ Documentation/howto/firewalld.rst \ Documentation/howto/ipsec.rst \ Documentation/howto/ssl.rst \ Documentation/howto/openstack-containers.rst \ Documentation/ref/index.rst \ Documentation/faq/index.rst \ Documentation/faq/contributing.rst \ Documentation/faq/general.rst \ Documentation/internals/index.rst \ Documentation/internals/authors.rst \ Documentation/internals/bugs.rst \ Documentation/internals/charter.rst \ Documentation/internals/committer-emeritus-status.rst \ Documentation/internals/committer-grant-revocation.rst \ Documentation/internals/committer-responsibilities.rst \ Documentation/internals/documentation.rst \ Documentation/internals/mailing-lists.rst \ Documentation/internals/maintainers.rst \ Documentation/internals/ovs_submodule.rst \ Documentation/internals/patchwork.rst \ Documentation/internals/release-process.rst \ Documentation/internals/security.rst \ Documentation/internals/contributing/index.rst \ Documentation/internals/contributing/backporting-patches.rst \ Documentation/internals/contributing/inclusive-language.rst \ Documentation/internals/contributing/coding-style.rst \ Documentation/internals/contributing/documentation-style.rst \ Documentation/internals/contributing/submitting-patches.rst \ Documentation/requirements.txt \ $(addprefix Documentation/ref/,$(RST_MANPAGES) $(RST_MANPAGES_NOINST)) FLAKE8_PYFILES += Documentation/conf.py EXTRA_DIST += $(DOC_SOURCE) # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXSRCDIR = $(srcdir)/Documentation SPHINXBUILDDIR = $(builddir)/Documentation/_build # Internal variables. ALLSPHINXOPTS = -W -n -d $(SPHINXBUILDDIR)/doctrees $(SPHINXOPTS) $(SPHINXSRCDIR) sphinx_verbose = $(sphinx_verbose_@AM_V@) sphinx_verbose_ = $(sphinx_verbose_@AM_DEFAULT_V@) sphinx_verbose_0 = -q if HAVE_SPHINX docs-check: $(DOC_SOURCE) $(AM_V_GEN)$(SPHINXBUILD) $(sphinx_verbose) -b html $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/html && touch $@ $(AM_V_GEN)$(SPHINXBUILD) $(sphinx_verbose) -b man $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/man && touch $@ ALL_LOCAL += docs-check CLEANFILES += docs-check check-docs: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(SPHINXBUILDDIR)/linkcheck clean-docs: rm -rf $(SPHINXBUILDDIR) rm -f docs-check CLEAN_LOCAL += clean-docs endif .PHONY: check-docs .PHONY: clean-docs # Installing manpages based on rST. # # The docs-check target converts the rST files listed in RST_MANPAGES # into nroff manpages in Documentation/_build/man. The easiest way to # get these installed by "make install" is to write our own helper # rules. # rST formatted manpages under Documentation/ref. RST_MANPAGES = # rST formatted manpages that we don't want to install because they # document stuff that only works with a build tree, not with an # installed OVS. RST_MANPAGES_NOINST = ovn-sim.1.rst # The GNU standards say that these variables should control # installation directories for manpages in each section. Automake # will define them for us only if it sees that a manpage in the # appropriate section is to be installed through its built-in feature. # Since we're working independently, for best safety, we need to # define them ourselves. man1dir = $(mandir)/man1 man2dir = $(mandir)/man2 man3dir = $(mandir)/man3 man4dir = $(mandir)/man4 man5dir = $(mandir)/man5 man6dir = $(mandir)/man6 man7dir = $(mandir)/man7 man8dir = $(mandir)/man8 man9dir = $(mandir)/man9 # Set a shell variable for each manpage directory. set_mandirs = \ man1dir='$(man1dir)' \ man2dir='$(man2dir)' \ man3dir='$(man3dir)' \ man4dir='$(man4dir)' \ man5dir='$(man5dir)' \ man6dir='$(man6dir)' \ man7dir='$(man7dir)' \ man8dir='$(man8dir)' \ man9dir='$(man9dir)' # Given an $rst of "ovs-vlan-test.8.rst", sets $stem to # "ovs-vlan-test", $section to "8", and $mandir to $man8dir. extract_stem_and_section = \ stem=`echo "$$rst" | sed -n 's/^\(.*\)\.\([0-9]\).rst$$/\1/p'`; \ section=`echo "$$rst" | sed -n 's/^\(.*\)\.\([0-9]\).rst$$/\2/p'`; \ test -n "$$section" || { echo "$$rst: cannot infer manpage section from filename" 2>&1; continue; }; \ eval "mandir=\$$man$${section}dir"; \ test -n "$$mandir" || { echo "unknown directory for manpage section $$section"; continue; } INSTALL_DATA_LOCAL += install-man-rst if HAVE_SPHINX install-man-rst: docs-check @$(set_mandirs); \ for rst in $(RST_MANPAGES) $(EXTRA_RST_MANPAGES); do \ $(extract_stem_and_section); \ echo " $(MKDIR_P) '$(DESTDIR)'\"$$mandir\""; \ $(MKDIR_P) '$(DESTDIR)'"$$mandir"; \ echo " $(INSTALL_DATA) $(SPHINXBUILDDIR)/man/$$stem.$$section '$(DESTDIR)'\"$$mandir/$$stem.$$section\""; \ $(INSTALL_DATA) $(SPHINXBUILDDIR)/man/$$stem.$$section '$(DESTDIR)'"$$mandir/$$stem.$$section"; \ done else install-man-rst: @: endif UNINSTALL_LOCAL += uninstall-man-rst uninstall-man-rst: @$(set_mandirs); \ for rst in $(RST_MANPAGES); do \ $(extract_stem_and_section); \ echo "rm -f '$(DESTDIR)'\"$$mandir/$$stem.$$section\""; \ rm -f '$(DESTDIR)'"$$mandir/$$stem.$$section"; \ done ovn-25.09.0~git20250813.23884f5/Documentation/conf.py000066400000000000000000000076541504532661100212710ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Open Virtual Network (OVN) documentation build configuration file, created by # sphinx-quickstart on Fri Sep 30 09:57:36 2016. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import importlib import string import sys use_rtd_theme = importlib.util.find_spec('sphinx_rtd_theme') is not None if not use_rtd_theme: print("Cannot find 'sphinx_rtd_theme' package. " "Falling back to default theme.") # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # needs_sphinx = '1.1' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['sphinx.ext.todo'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'contents' # General information about the project. project = u'Open Virtual Network (OVN)' copyright = u'2020-2024, The Open Virtual Network (OVN) Development Community' author = u'The Open Virtual Network (OVN) Development Community' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The full version, including alpha/beta/rc tags. release = None filename = "../configure.ac" with open(filename, 'r') as f: for line in f: if 'AC_INIT' in line: # Parse "AC_INIT(openvswitch, 2.7.90, bugs@openvswitch.org)": release = line.split(',')[1].strip(string.whitespace + '[]') break if release is None: sys.stderr.write('%s: failed to determine Open Virtual Network (OVN) ' 'version\n' % filename) sys.exit(1) # The short X.Y version. # # However, it's important to know the difference between, e.g., 2.7 # and 2.7.90, which can be very different versions (2.7.90 may be much # closer to 2.8 than to 2.7), so check for that. version = release if '.90' in release else '.'.join(release.split('.')[0:2]) # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # If true, check the validity of #anchors in links. linkcheck_anchors = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # if use_rtd_theme: html_theme = 'sphinx_rtd_theme' # The name of an image file (relative to this directory) to place at the top # of the sidebar. # html_logo = '_static/logo.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). _man_pages = [ ('ovn-sim.1', u'Open Virtual Network simulator environment'), ] # Generate list of (path, name, description, [author, ...], section) man_pages = [ ('ref/%s' % file_name, file_name.split('.', 1)[0], description, [author], file_name.split('.', 1)[1]) for file_name, description in _man_pages] ovn-25.09.0~git20250813.23884f5/Documentation/contents.rst000066400000000000000000000022551504532661100223510ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================================= Open Virtual Network (OVN) Documentation Contents ================================================= .. toctree:: :maxdepth: 3 index .. toctree:: :maxdepth: 3 intro/index tutorials/index topics/index howto/index ref/index faq/index internals/index ovn-25.09.0~git20250813.23884f5/Documentation/faq/000077500000000000000000000000001504532661100205255ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/faq/contributing.rst000066400000000000000000000076011504532661100237720ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =========== Development =========== Q: How do I apply patches from email? A: You can use ``git am`` on raw email contents, either from a file saved by or piped from an email client. In ``mutt``, for example, when you are viewing a patch, you can apply it to the tree in ~/ovs by issuing the command ``|cd ~/ovs && git am``. If you are an OVS committer, you might want to add ``-s`` to sign off on the patch as part of applying it. If you do this often, then you can make the keystrokes ``,a`` shorthand for it by adding the following line to your ``.muttrc``: macro index,pager ,a "cd ~/ovs && git am -s" "apply patch" ``git am`` has a problem with some email messages from the ovs-dev list for which the mailing list manager edits the From: address, replacing it by the list's own address. The mailing list manager must do this for messages whose sender's email domain has DMARC configured, because receivers will otherwise discard these messages when they do not come directly from the sender's email domain. This editing makes the patches look like they come from the mailing list instead of the author. To work around this problem, one can use the following wrapper script for ``git am``:: #! /bin/sh tmp=$(mktemp) cat >$tmp if grep '^From:.*via dev.*' "$tmp" >/dev/null 2>&1; then sed '/^From:.*via dev.*/d s/^[Rr]eply-[tT]o:/From:/' $tmp else cat "$tmp" fi | git am "$@" rm "$tmp" Another way to apply emailed patches is to use the ``pwclient`` program, which can obtain patches from patchwork and apply them directly. Download ``pwclient`` at https://patchwork.ozlabs.org/project/ovn/. You probably want to set up a ``.pwclientrc`` that looks something like this:: [options] default=ovn signoff=true [ovn] url=https://patchwork.ozlabs.org/xmlrpc/ After you install ``pwclient``, you can apply a patch from patchwork with ``pwclient git-am #``, where # is the patch's number. (This fails with certain patches that contain form-feeds, due to a limitation of the protocol underlying ``pwclient``.) Another way to apply patches directly from patchwork which supports applying patch series is to use the ``git-pw`` program. It can be obtained with ``pip install git-pw``. Alternative installation instructions and general documentation can be found at https://patchwork.readthedocs.io/projects/git-pw/en/latest/. You need to use your ovn patchwork login or create one at https://patchwork.ozlabs.org/register/. The following can then be set on the command line with ``git config`` or through a ``.gitconfig`` like this:: [pw] server=https://patchwork.ozlabs.org/api/1.0 project=ovn username= password= Patch series can be listed with ``git-pw series list`` and applied with ``git-pw series apply #``, where # is the series number. Individual patches can be applied with ``git-pw patch apply #``, where # is the patch number. ovn-25.09.0~git20250813.23884f5/Documentation/faq/general.rst000066400000000000000000000170011504532661100226730ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======= General ======= Q: What is OVN? A: OVN, the Open Virtual Network, is a system to support virtual network abstraction. OVN complements the existing capabilities of OVS to add native support for virtual network abstractions, such as virtual L2 and L3 overlays and security groups. OVN is intended to be used by cloud management software (CMS). For details about the architecture of OVN, see the ovn-architecture manpage. Some high-level features offered by OVN include * Distributed virtual routers * Distributed logical switches * Access Control Lists * DHCP * DNS server Q: How can I try OVN? A: The OVN source code can be built on a Linux system. You can build and experiment with OVN on any Linux machine. Packages for various Linux distributions are available on many platforms, including: Debian, Ubuntu, Fedora. Q: Why does OVN use Geneve instead of VLANs or VXLAN (or GRE)? A: OVN implements a fairly sophisticated packet processing pipeline in "logical datapaths" that can implement switching or routing functionality. A logical datapath has an ingress pipeline and an egress pipeline, and each of these pipelines can include logic based on packet fields as well as packet metadata such as the logical ingress and egress ports (the latter only in the egress pipeline). The processing for a logical datapath can be split across hypervisors. In particular, when a logical ingress pipeline executes an "output" action, OVN passes the packet to the egress pipeline on the hypervisor (or, in the case of output to a logical multicast group, hypervisors) on which the logical egress port is located. If this hypervisor is not the same as the ingress hypervisor, then the packet has to be transmitted across a physical network. This situation is where tunneling comes in. To send the packet to another hypervisor, OVN encapsulates it with a tunnel protocol and sends the encapsulated packet across the physical network. When the remote hypervisor receives the tunnel packet, it decapsulates it and passes it through the logical egress pipeline. To do so, it also needs the metadata, that is, the logical ingress and egress ports. Thus, to implement OVN logical packet processing, at least the following metadata must pass across the physical network: * Logical datapath ID, a 24-bit identifier. In Geneve, OVN uses the VNI to hold the logical datapath ID. * Logical ingress port, a 15-bit identifier. In Geneve, OVN uses an option to hold the logical ingress port. * Logical egress port, a 16-bit identifier. In Geneve, OVN uses an option to hold the logical egress port. See ``ovn-architecture(7)``, under "Tunnel Encapsulations", for details. Together, these metadata require 24 + 15 + 16 = 55 bits. GRE provides 32 bits, VXLAN provides 24, and VLAN only provides 12. Most notably, if logical egress pipelines do not match on the logical ingress port, thereby restricting the class of ACLs available to users, then this eliminates 15 bits, bringing the requirement down to 40 bits. At this point, one can choose to limit the size of the OVN logical network in various ways, e.g.: * 16 bits of logical datapaths + 16 bits of logical egress ports. This combination fits within a 32-bit GRE tunnel key. * 12 bits of logical datapaths + 12 bits of logical egress ports. This combination fits within a 24-bit VXLAN VNI. * It's difficult to identify an acceptable compromise for a VLAN-based deployment. These compromises wouldn't suit every site, since some deployments may need to allocate more bits to the datapath or egress port identifiers. As a side note, OVN does support VXLAN for use with ASIC-based top of rack switches, using ``ovn-controller-vtep(8)`` and the OVSDB VTEP schema described in ``vtep(5)``, but this limits the features available from OVN to the subset available from the VTEP schema. Q: How can I contribute to the OVN Community? A: You can start by joining the mailing lists and helping to answer questions. You can also suggest improvements to documentation. If you have a feature or bug you would like to work on, send a mail to one of the :doc:`mailing lists `. Q: What does it mean when a feature is marked "experimental"? A: Experimental features are marked this way because of one of several reasons: * The developer was only able to test the feature in a limited environment. Therefore the feature may not always work as intended in all environments. * During review, the potential for failure was noticed, but the circumstances that would lead to that failure were hard to nail down or were strictly theoretical. * What exists in OVN may be an early version of a more fleshed-out feature to come in a later version. * The feature was developed against a draft RFC that is subject to change when the RFC is published. * The feature was developed based on observations of how a specific vendor implements a feature, rather than using IETF standards or other documentated specifications. A feature may be declared experimental for other reasons as well, but the above are the most common. When a feature is marked experimental, it has the following properties: * The feature must be opt-in. The feature must be disabled by default. When the feature is disabled, it must have no bearing on other OVN functionality. * Configuration and implementation details of the feature are subject to change between major or minor versions of OVN. * Users make use of this feature at their own risk. Users are free to file issues against the feature, but developers are more likely to prioritize work on non-experimental features first. * Experimental features may be removed. For instance, if an experimental feature exposes a security risk, it may be removed rather than repaired. The hope is that experimental features will eventually lose the "experimental" marker and become a core feature. However, there is no specific test or process defined for when a feature no longer needs to be considered experimental. This typically will be decided collectively by OVN maintainers. Q: How is a feature marked "experimental"? A: Experimental features must contain the following note in their man pages (ovn-nb.5, ovn-sb.5, ovn-controller.8, etc): "NOTE: this feature is experimental and may be subject to removal/change in the future.: ovn-25.09.0~git20250813.23884f5/Documentation/faq/index.rst000066400000000000000000000020711504532661100223660ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============================== Open Virtual Network (OVN) FAQ ============================== .. toctree:: :maxdepth: 2 contributing general ovn-25.09.0~git20250813.23884f5/Documentation/group-selection-method-property.txt000066400000000000000000000114361504532661100270030ustar00rootroot00000000000000Proposal for Group Selection Method Property Version: 0.0.3 Author: Simon Horman , et al. Initial Public Revision: September 2014 Contents ======== 1. Introduction 2. How it Works 3. Experimenter Id 4. Experimenter Messages 5. History 1. Introduction =============== This text describes a Netronome Extension to (draft) OpenFlow 1.5 that allows a controller to provide more information on the selection method for select groups. This proposal is in the form of an enhanced select group type. This may subsequently be proposed as an extension or update to the OpenFlow specification. 2. How it works =============== A new Netronome group experimenter property is defined which provides compatibility with the group mod message defined in draft Open Flow 1.5 (also known as ONF EXT-350) and allows parameters for the selection method of select groups to be passed by the controller. In particular it allows controllers to: * Specify the fields used for bucket selection by the select group. * Designate the selection method used. * Provide a non-field parameter to the selection method. 3. Experimenter ID ================== The Experimenter ID of this extension is: NTR_VENDOR_ID = 0x0000154d 4. Group Experimenter Property ============================== The following group property experimenter type defined by this extension. enum ntr_group_mod_subtype { NTRT_SELECTION_METHOD = 1, }; Modifications to the group table from the controller may be done with a OFPT_GROUP_MOD message described (draft) Open Flow 1.5. Group Entry Message. Of relevance here is that (draft) Open Flow 1.5 group messages have properties. This proposal is defined in terms of an implementation of struct ofp_group_prop_experimenter which is described in (draft) Open Flow 1.5. The implementation is: struct ntr_group_prop_selection_method { ovs_be16 type; /* OFPGPT_EXPERIMENTER. */ ovs_be16 length; /* Length in bytes of this property. */ ovs_be32 experimenter; /* NTR_VENDOR_ID. */ ovs_be32 exp_type; /* NTRT_SELECTION_METHOD. */ ovs_be32 pad; char selection_method[NTR_MAX_SELECTION_METHOD_LEN]; /* Null-terminated */ ovs_be64 selection_method_param; /* Non-Field parameter for * bucket selection. */ /* Followed by: * - Exactly (length - 40) (possibly 0) bytes containing OXM TLVs, then * - Exactly ((length + 7)/8*8 - length) (between 0 and 7) bytes of * all-zero bytes * In summary, ntr_group_prop_selection_method is padded as needed, * to make its overall size a multiple of 8, to preserve alignment * in structures using it. */ /* uint8_t field_array[0]; */ /* Zero or more fields encoded as * OXM TLVs where the has_mask bit must * be zero and the value it specifies is * a mask to apply to packet fields and * then input them to the selection * method of a select group. */ /* uint8_t pad2[0]; */ }; OFP_ASSERT(sizeof(struct ntr_group_mod) == 40); This property may only be used with group mod messages whose: * command is OFPGC_ADD or OFPGC_MODIFY; and * type is OFPGT_SELECT The type field is the OFPGPT_EXPERIMENTER which is defined in EXT-350 as 0xffff. The experimenter field is the Experimenter ID (see 3). The exp_type field is NTRT_SELECTION_METHOD. The group selection_method is a null-terminated string which if non-zero length specifies a selection method known to an underlying layer of the switch. The value of NTR_MAX_SELECTION_METHOD_LEN is 16. The group selection_method may be zero-length to request compatibility with Open Flow 1.4. The selection_method_param provides a non-field parameter for the group selection_method. It must be all-zeros unless the group selection_method is non-zero length. The selection_method_param may for example be used as an initial value for the hash of a hash group selection method. The fields field is an ofp_match structure which includes the fields which should be used as inputs to bucket selection. ofp_match is described in Open Flow 1.4 section 7.2.2 Flow Match Structures. Fields must not be specified unless the group selection_method is non-zero length. The pre-requisites for fields specified must be satisfied in the match for any flow that uses the group. Masking is allowed but not required for fields whose TLVs allow masking. The fields may for example be used as the fields that are hashed by a hash group selection method. 5. History ========== This proposal has been developed independently of any similar work in this area. No such work is known. ovn-25.09.0~git20250813.23884f5/Documentation/howto/000077500000000000000000000000001504532661100211165ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/howto/docker.rst000066400000000000000000000265501504532661100231270ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================================== Open Virtual Networking With Docker =================================== This document describes how to use Open Virtual Networking with Docker 1.9.0 or later. .. important:: Requires Docker version 1.9.0 or later. Only Docker 1.9.0+ comes with support for multi-host networking. Consult www.docker.com for instructions on how to install Docker. .. note:: You must build and install Open vSwitch before proceeding with the below guide. Refer to :doc:`/intro/install/index` for more information. Setup ----- For multi-host networking with OVN and Docker, Docker has to be started with a distributed key-value store. For example, if you decide to use consul as your distributed key-value store and your host IP address is ``$HOST_IP``, start your Docker daemon with:: $ docker daemon --cluster-store=consul://127.0.0.1:8500 \ --cluster-advertise=$HOST_IP:0 OVN provides network virtualization to containers. OVN's integration with Docker currently works in two modes - the "underlay" mode or the "overlay" mode. In the "underlay" mode, OVN requires a OpenStack setup to provide container networking. In this mode, one can create logical networks and can have containers running inside VMs, standalone VMs (without having any containers running inside them) and physical machines connected to the same logical network. This is a multi-tenant, multi-host solution. In the "overlay" mode, OVN can create a logical network amongst containers running on multiple hosts. This is a single-tenant (extendable to multi-tenants depending on the security characteristics of the workloads), multi-host solution. In this mode, you do not need a pre-created OpenStack setup. For both the modes to work, a user has to install and start Open vSwitch in each VM/host that they plan to run their containers on. .. _docker-overlay: The "overlay" mode ------------------ .. note:: OVN in "overlay" mode needs a minimum Open vSwitch version of 2.5. 1. Start the central components. OVN architecture has a central component which stores your networking intent in a database. On one of your machines, with an IP Address of ``$CENTRAL_IP``, where you have installed and started Open vSwitch, you will need to start some central components. Start ovn-northd daemon. This daemon translates networking intent from Docker stored in the OVN\_Northbound database to logical flows in ``OVN_Southbound`` database. For example:: $ /usr/share/ovn/scripts/ovn-ctl start_northd With Open vSwitch version of 2.7 or greater, you need to run the following additional commands (Please read the manpages of ovn-nb for more control on the types of connection allowed.) :: $ ovn-nbctl set-connection ptcp:6641 $ ovn-sbctl set-connection ptcp:6642 2. One time setup On each host, where you plan to spawn your containers, you will need to run the below command once. You may need to run it again if your OVS database gets cleared. It is harmless to run it again in any case:: $ ovs-vsctl set Open_vSwitch . \ external_ids:ovn-remote="tcp:$CENTRAL_IP:6642" \ external_ids:ovn-nb="tcp:$CENTRAL_IP:6641" \ external_ids:ovn-encap-ip=$LOCAL_IP \ external_ids:ovn-encap-type="$ENCAP_TYPE" where: ``$LOCAL_IP`` is the IP address via which other hosts can reach this host. This acts as your local tunnel endpoint. ``$ENCAP_TYPE`` is the type of tunnel that you would like to use for overlay networking. The options are ``geneve`` or ``vxlan``. Your kernel must have support for your chosen ``$ENCAP_TYPE``. You will need a minimum Linux kernel version of 3.18 for ``geneve``. You can verify whether you have the support in your kernel as follows:: $ lsmod | grep $ENCAP_TYPE In addition, each Open vSwitch instance in an OVN deployment needs a unique, persistent identifier, called the ``system-id``. If you install OVS from distribution packaging for Open vSwitch (e.g. .deb or .rpm packages), or if you use the ovs-ctl utility included with Open vSwitch, it automatically configures a system-id. If you start Open vSwitch manually, you should set one up yourself. For example:: $ id_file=/etc/openvswitch/system-id.conf $ test -e $id_file || uuidgen > $id_file $ ovs-vsctl set Open_vSwitch . external_ids:system-id=$(cat $id_file) 3. Start the ``ovn-controller``. You need to run the below command on every boot:: $ /usr/share/ovn/scripts/ovn-ctl start_controller 4. Start the Open vSwitch network driver. By default Docker uses Linux bridge for networking. But it has support for external drivers. To use Open vSwitch instead of the Linux bridge, you will need to start the Open vSwitch driver. The Open vSwitch driver uses the Python's flask module to listen to Docker's networking api calls. So, if your host does not have Python's flask module, install it:: $ sudo pip install Flask Start the Open vSwitch driver on every host where you plan to create your containers. Refer to the note on ``$OVS_PYTHON_LIBS_PATH`` that is used below at the end of this document:: $ PYTHONPATH=$OVS_PYTHON_LIBS_PATH ovn-docker-overlay-driver --detach .. note:: The ``$OVS_PYTHON_LIBS_PATH`` variable should point to the directory where Open vSwitch Python modules are installed. If you installed Open vSwitch Python modules via the Debian package of ``python-openvswitch`` or via pip by running ``pip install ovs``, you do not need to specify the PATH. If you installed it by following the instructions in :doc:`/intro/install/general`, then you should specify the PATH. In this case, the PATH depends on the options passed to ``./configure``. It is usually either ``/usr/share/openvswitch/python`` or ``/usr/local/share/openvswitch/python`` Docker has inbuilt primitives that closely match OVN's logical switches and logical port concepts. Consult Docker's documentation for all the possible commands. Here are some examples. Create a logical switch ~~~~~~~~~~~~~~~~~~~~~~~ To create a logical switch with name 'foo', on subnet '192.168.1.0/24', run:: $ NID=`docker network create -d openvswitch --subnet=192.168.1.0/24 foo` List all logical switches ~~~~~~~~~~~~~~~~~~~~~~~~~ :: $ docker network ls You can also look at this logical switch in OVN's northbound database by running the following command:: $ ovn-nbctl --db=tcp:$CENTRAL_IP:6640 ls-list Delete a logical switch ~~~~~~~~~~~~~~~~~~~~~~~ :: $ docker network rm bar Create a logical port ~~~~~~~~~~~~~~~~~~~~~ Docker creates your logical port and attaches it to the logical network in a single step. For example, to attach a logical port to network ``foo`` inside container busybox, run:: $ docker run -itd --net=foo --name=busybox busybox List all logical ports ~~~~~~~~~~~~~~~~~~~~~~ Docker does not currently have a CLI command to list all logical ports but you can look at them in the OVN database by running:: $ ovn-nbctl --db=tcp:$CENTRAL_IP:6640 lsp-list $NID Create and attach a logical port to a running container ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: $ docker network create -d openvswitch --subnet=192.168.2.0/24 bar $ docker network connect bar busybox Detach and delete a logical port from a running container ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can delete your logical port and detach it from a running container by running: :: $ docker network disconnect bar busybox .. _docker-underlay: The "underlay" mode ------------------- .. note:: This mode requires that you have a OpenStack setup pre-installed with OVN providing the underlay networking. 1. One time setup A OpenStack tenant creates a VM with a single network interface (or multiple) that belongs to management logical networks. The tenant needs to fetch the port-id associated with the interface via which he plans to send the container traffic inside the spawned VM. This can be obtained by running the below command to fetch the 'id' associated with the VM:: $ nova list and then by running:: $ neutron port-list --device_id=$id Inside the VM, download the OpenStack RC file that contains the tenant information (henceforth referred to as ``openrc.sh``). Edit the file and add the previously obtained port-id information to the file by appending the following line:: $ export OS_VIF_ID=$port_id After this edit, the file will look something like:: #!/bin/bash export OS_AUTH_URL=http://10.33.75.122:5000/v2.0 export OS_TENANT_ID=fab106b215d943c3bad519492278443d export OS_TENANT_NAME="demo" export OS_USERNAME="demo" export OS_VIF_ID=e798c371-85f4-4f2d-ad65-d09dd1d3c1c9 2. Create the Open vSwitch bridge If your VM has one ethernet interface (e.g.: 'eth0'), you will need to add that device as a port to an Open vSwitch bridge 'breth0' and move its IP address and route related information to that bridge. (If it has multiple network interfaces, you will need to create and attach an Open vSwitch bridge for the interface via which you plan to send your container traffic.) If you use DHCP to obtain an IP address, then you should kill the DHCP client that was listening on the physical Ethernet interface (e.g. eth0) and start one listening on the Open vSwitch bridge (e.g. breth0). Depending on your VM, you can make the above step persistent across reboots. For example, if your VM is Debian/Ubuntu-based, read `openvswitch-switch.README.Debian` found in `debian` folder. If your VM is RHEL-based, refer to :doc:`/intro/install/fedora`. 3. Start the Open vSwitch network driver The Open vSwitch driver uses the Python's flask module to listen to Docker's networking api calls. The driver also uses OpenStack's ``python-neutronclient`` libraries. If your host does not have Python's ``flask`` module or ``python-neutronclient`` you must install them. For example:: $ pip install python-neutronclient $ pip install Flask Once installed, source the ``openrc`` file:: $ . ./openrc.sh Start the network driver and provide your OpenStack tenant password when prompted:: $ PYTHONPATH=$OVS_PYTHON_LIBS_PATH ovn-docker-underlay-driver \ --bridge breth0 --detach From here-on you can use the same Docker commands as described in `docker-overlay`_. Refer to the ovs-architecture man pages (``man ovn-architecture``) to understand OVN's architecture in detail. ovn-25.09.0~git20250813.23884f5/Documentation/howto/firewalld.rst000066400000000000000000000100561504532661100236230ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================================== Open Virtual Network With firewalld =================================== firewalld is a service that allows for easy administration of firewalls. OVN ships with a set of service files that can be used with firewalld to allow for remote connections to the northbound and southbound databases. This guide will describe how you can use these files with your existing firewalld setup. Setup and administration of firewalld is outside the scope of this document. Installation ------------ If you have installed OVN from an RPM, then the service files for firewalld will automatically be installed in ``/usr/lib/firewalld/services``. Installation from RPM includes installation from the yum or dnf package managers. If you have installed OVN from source, then from the top level source directory, issue the following commands to copy the firewalld service files: :: $ cp rhel/usr_lib_firewalld_services_ovn-central-firewall-service.xml \ /etc/firewalld/services/ $ cp rhel/usr_lib_firewalld_services_ovn-host-firewall-service.xml \ /etc/firewalld/services/ Activation ---------- Assuming you are already running firewalld, you can issue the following commands to enable the OVN services. On the central server (the one running ``ovn-northd``), issue the following:: $ firewall-cmd --zone=public --add-service=ovn-central-firewall-service This will open TCP ports 6641 and 6642, allowing for remote connections to the northbound and southbound databases. On the OVN hosts (the ones running ``ovn-controller``), issue the following:: $ firewall-cmd --zone=public --add-service=ovn-host-firewall-service This will open UDP port 6081, allowing for geneve traffic to flow between the controllers. Variations ---------- When installing the XML service files, you have the choice of copying them to ``/etc/firewalld/services`` or ``/usr/lib/firewalld/services``. The former is recommend since the latter can be overwritten if firewalld is upgraded. The above commands assumed your underlay network interfaces are in the "public" firewalld zone. If your underlay network interfaces are in a separate zone, then adjust the above commands accordingly. The ``--permanent`` option may be passed to the above firewall-cmd invocations in order for the services to be permanently added to the firewalld configuration. This way it is not necessary to re-issue the commands each time the firewalld service restarts. The ovn-host-firewall-service only opens port 6081. This is because the default protocol for OVN tunnels is geneve. If you are using a different encapsulation protocol, you will need to modify the XML service file to open the appropriate port(s). For VXLAN, open port 4789. Recommendations --------------- The firewalld service files included with the OVS repo are meant as a convenience for firewalld users. All that the service files do is to open the common ports used by OVN. No additional security is provided. To ensure a more secure environment, it is a good idea to do the following * Use tools such as iptables or nftables to restrict access to known hosts. * Use SSL/TLS for all remote connections to OVN databases. * Use role-based access control for connections to the OVN southbound database. ovn-25.09.0~git20250813.23884f5/Documentation/howto/index.rst000066400000000000000000000023351504532661100227620ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============= How-to Guides ============= Answers to common "How do I?"-style questions. For more information on the topics covered herein, refer to :doc:`/topics/index`. OVS --- .. toctree:: :maxdepth: 2 ipsec ssl OVN --- .. toctree:: :maxdepth: 1 docker openstack-containers firewalld ovn-25.09.0~git20250813.23884f5/Documentation/howto/ipsec.rst000066400000000000000000000020251504532661100227520ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================================= Encrypt Open vSwitch Tunnels with IPsec ======================================= Please refer to the Open vSwitch documentation on ipsec. ovn-25.09.0~git20250813.23884f5/Documentation/howto/openstack-containers.rst000066400000000000000000000156001504532661100260040ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================================ Integration of Containers with OVN and OpenStack ================================================ Isolation between containers is weaker than isolation between VMs, so some environments deploy containers for different tenants in separate VMs as an additional security measure. This document describes creation of containers inside VMs and how they can be made part of the logical networks securely. The created logical network can include VMs, containers and physical machines as endpoints. To better understand the proposed integration of containers with OVN and OpenStack, this document describes the end to end workflow with an example. * A OpenStack tenant creates a VM (say VM-A) with a single network interface that belongs to a management logical network. The VM is meant to host containers. OpenStack Nova chooses the hypervisor on which VM-A is created. * A Neutron port may have been created in advance and passed in to Nova with the request to create a new VM. If not, Nova will issue a request to Neutron to create a new port. The ID of the logical port from Neutron will also be used as the vif-id for the virtual network interface (VIF) of VM-A. * When VM-A is created on a hypervisor, its VIF gets added to the Open vSwitch integration bridge. This creates a row in the Interface table of the ``Open_vSwitch`` database. As explained in the :doc:`integration guide `, the vif-id associated with the VM network interface gets added in the ``external_ids:iface-id`` column of the newly created row in the Interface table. * Since VM-A belongs to a logical network, it gets an IP address. This IP address is used to spawn containers (either manually or through container orchestration systems) inside that VM and to monitor the health of the created containers. * The vif-id associated with the VM's network interface can be obtained by making a call to Neutron using tenant credentials. * This flow assumes a component called a "container network plugin". If you take Docker as an example for containers, you could envision the plugin to be either a wrapper around Docker or a feature of Docker itself that understands how to perform part of this workflow to get a container connected to a logical network managed by Neutron. The rest of the flow refers to this logical component that does not yet exist as the "container network plugin". * All the calls to Neutron will need tenant credentials. These calls can either be made from inside the tenant VM as part of a container network plugin or from outside the tenant VM (if the tenant is not comfortable using temporary Keystone tokens from inside the tenant VMs). For simplicity, this document explains the work flow using the former method. * The container hosting VM will need Open vSwitch installed in it. The only work for Open vSwitch inside the VM is to tag network traffic coming from containers. * When a container needs to be created inside the VM with a container network interface that is expected to be attached to a particular logical switch, the network plugin in that VM chooses any unused VLAN (This VLAN tag only needs to be unique inside that VM. This limits the number of container interfaces to 4096 inside a single VM). This VLAN tag is stripped out in the hypervisor by OVN and is only useful as a context (or metadata) for OVN. * The container network plugin then makes a call to Neutron to create a logical port. In addition to all the inputs that a call to create a port in Neutron that are currently needed, it sends the vif-id and the VLAN tag as inputs. * Neutron in turn will verify that the vif-id belongs to the tenant in question and then uses the OVN specific plugin to create a new row in the Logical_Switch_Port table of the OVN Northbound Database. Neutron responds back with an IP address and MAC address for that network interface. So Neutron becomes the IPAM system and provides unique IP and MAC addresses across VMs and containers in the same logical network. * The Neutron API call above to create a logical port for the container could add a relatively significant amount of time to container creation. However, an optimization is possible here. Logical ports could be created in advance and reused by the container system doing container orchestration. Additional Neutron API calls would only be needed if the port needs to be attached to a different logical network. * When a container is eventually deleted, the network plugin in that VM may make a call to Neutron to delete that port. Neutron in turn will delete the entry in the ``Logical_Switch_Port`` table of the OVN Northbound Database. As an example, consider Docker containers. Since Docker currently does not have a network plugin feature, this example uses a hypothetical wrapper around Docker to make calls to Neutron. * Create a Logical switch:: $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f create network LS1 The above command will make a call to Neutron with the credentials to create a logical switch. The above is optional if the logical switch has already been created from outside the VM. * List networks available to the tenant:: $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f list networks * Create a container and attach a interface to the previously created switch as a logical port:: $ ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f --vif-id=$VIF_ID \ --network=LS1 run -d --net=none ubuntu:14.04 /bin/sh -c \ "while true; do echo hello world; sleep 1; done" The above command will make a call to Neutron with all the inputs it currently needs to create a logical port. In addition, it passes the $VIF_ID and a unused VLAN. Neutron will add that information in OVN and return back a MAC address and IP address for that interface. ovn-docker will then create a veth pair, insert one end inside the container as 'eth0' and the other end as a port of a local OVS bridge as an access port of the chosen VLAN. ovn-25.09.0~git20250813.23884f5/Documentation/howto/ssl.rst000066400000000000000000000020051504532661100224460ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================= Open Virtual Network with SSL/TLS ================================= Please refer to the Open vSwitch documentation on SSL/TLS. ovn-25.09.0~git20250813.23884f5/Documentation/index.rst000066400000000000000000000070411504532661100216210ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================================== Open Virtual Network (OVN) Documentation ======================================== How the Documentation is Organised ---------------------------------- The Open Virtual Network (OVN) documentation is organised into multiple sections: - :doc:`Installation guides ` guide you through installing Open Open Virtual Network (OVN) on a variety of different platforms - :doc:`Tutorials ` take you through a series of steps to configure OVS and OVN in sandboxed environments - :doc:`Topic guides ` provide a high level overview of OVS and OVN internals and operation - :doc:`How-to guides ` are recipes or use-cases for OVS and OVN. They are more advanced than the tutorials. - :doc:`Frequently Asked Questions ` provide general insight into a variety of topics related to configuration and operation of OVS and OVN. First Steps ----------- Getting started with Open Virtual Network (OVN) for Open vSwitch? Start here. - **Install:** :doc:`intro/install/general` | :doc:`intro/install/windows` - **Tutorials:** :doc:`tutorials/ovn-sandbox` | :doc:`tutorials/ovn-openstack` | :doc:`tutorials/ovn-ipsec` | :doc:`tutorials/ovn-rbac` Deeper Dive ----------- - **Architecture** :doc:`topics/integration` - **Testing** :doc:`topics/testing` - **Packaging:** :doc:`intro/install/debian` | :doc:`intro/install/fedora` The Open Virtual Network (OVN) Project -------------------------------------- Learn more about the Open Virtual Network (OVN) project and about how you can contribute: - **Community:** :doc:`internals/release-process` | :doc:`internals/authors` | :doc:`internals/mailing-lists` | :doc:`internals/patchwork` | :doc:`internals/bugs` | :doc:`internals/security` - **Contributing:** :doc:`internals/contributing/submitting-patches` | :doc:`internals/contributing/backporting-patches` | :doc:`internals/contributing/inclusive-language` | :doc:`internals/contributing/coding-style` - **Maintaining:** :doc:`internals/charter` | :doc:`internals/maintainers` | :doc:`internals/committer-responsibilities` | :doc:`internals/committer-grant-revocation` | :doc:`internals/committer-emeritus-status` - **Documentation:** :doc:`internals/contributing/documentation-style` | :doc:`Building OVN Documentation ` | :doc:`internals/documentation` Getting Help ------------- - Seeing an issue of potential bug? Report problems to bugs@openvswitch.org - Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or the :doc:`detailed table of contents `. ovn-25.09.0~git20250813.23884f5/Documentation/internals/000077500000000000000000000000001504532661100217555ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/internals/authors.rst000066400000000000000000000016011504532661100241720ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. .. include:: ../../AUTHORS.rst ovn-25.09.0~git20250813.23884f5/Documentation/internals/bugs.rst000066400000000000000000000041621504532661100234520ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ===================== Reporting Bugs in OVN ===================== We are eager to hear from users about problems that they have encountered with OVN. This file documents how best to report bugs so as to ensure that they can be fixed as quickly as possible. Please report bugs by sending email to bugs@openvswitch.org. For reporting security vulnerabilities, please read :doc:`security`. The most important parts of your bug report are the following: - What you did that make the problem appear. - What you expected to happen. - What actually happened. Please also include the following information: - The OVN version number (as output by ``ovn-controller --version``). - The Git commit number (as output by ``git rev-parse HEAD``), if you built from a Git snapshot. - Any local patches or changes you have applied (if any). The following are also handy sometimes: - The kernel version on which Open vSwitch is running (from ``/proc/version``) and the distribution and version number of your OS (e.g. "Centos 5.0"). - The contents of the northbound database. - Any other information that you think might be relevant. .. important:: bugs@openvswitch.org is a public mailing list, to which anyone can subscribe, so do not include confidential information in your bug report. ovn-25.09.0~git20250813.23884f5/Documentation/internals/charter.rst000066400000000000000000000272341504532661100241470ustar00rootroot00000000000000The Linux Foundation Open Virtual Network Charter ================================================= Effective November 4, 2019 This Charter sets forth the responsibilities and procedures for technical contribution to, and oversight of, the Open Virtual Network ("OVN") open collaboration project, which has been established as OVN a Series of LF Projects, LLC (the "Project"). LF Projects, LLC ("LF Projects") is a Delaware series limited liability company. All contributors (including committers, maintainers, and other technical positions) and other participants in the Project (collectively, "Collaborators") must comply with the terms of this Charter. 1. Mission and Scope of the Project a. The mission of the Project is to develop an open source system to support native virtual network abstractions, such as virtual L2 and L3 overlays and security groups for production-quality implementations that can operate at significant scale. b. The scope of the Project includes collaborative development under the Project License (as defined herein) supporting the mission, including documentation, testing, integration and the creation of other artifacts that aid the development, deployment, operation or adoption of the open source project. 2. Technical Steering Committee ("TSC") a. The Technical Steering Committee (the "TSC") will be responsible for all technical oversight of the open source Project. b. The TSC voting members are initially the Project's Committers. At the inception of the project, the Committers of the Project will be as set forth within the :doc:`/internals/maintainers` file within the Project's code repository. The TSC may choose an alternative approach for determining the voting members of the TSC, and any such alternative approach will be documented in the CONTRIBUTING file. Any meetings of the Technical Steering Committee are intended to be open to the public, and can be conducted electronically, via teleconference, or in person. c. TSC projects generally will involve Contributors and Committers. The TSC may adopt or modify roles so long as the roles are documented in the CONTRIBUTING file and other files that it references. Unless otherwise documented: i. Contributors include anyone in the technical community that contributes code, documentation, or other technical artifacts to the Project; ii. Committers are Contributors who have earned the ability to modify ("commit") source code, documentation or other technical artifacts in a project's repository; and iii. A Contributor may become a Committer following the guidelines set out by the TSC, currently available at :doc:`/internals/committer-grant-revocation`. A Committer may be removed per the same guidelines provided by the TSC. d. Participation in the Project through becoming a Contributor and Committer is open to anyone so long as they abide by the terms of this Charter. e. The TSC may (1) establish work flow procedures for the submission, approval, and closure/archiving of projects, (2) set requirements for the promotion of Contributors to Committer status, as applicable, and (3) amend, adjust, refine and/or eliminate the roles of Contributors, and Committers, and create new roles, and publicly document any TSC roles, as it sees fit. f. The TSC may elect a TSC Chair, who will preside over meetings of the TSC and will serve until their resignation or replacement by the TSC. g. Responsibilities: The TSC will be responsible for all aspects of oversight relating to the Project, which may include: i. coordinating the technical direction of the Project; ii. approving project or system proposals (including, but not limited to, incubation, deprecation, and changes to a sub-project's scope); iii. organizing sub-projects and removing sub-projects; iv. creating sub-committees or working groups to focus on cross-project technical issues and requirements; v. appointing representatives to work with other open source or open standards communities; vi. establishing community norms, workflows, issuing releases, and security issue reporting policies; vii. approving and implementing policies and processes for contributing (to be published in the CONTRIBUTING file) and coordinating with the series manager of the Project (as provided for in the Series Agreement, the "Series Manager") to resolve matters or concerns that may arise as set forth in Section 7 of this Charter; viii. discussions, seeking consensus, and where necessary, voting on technical matters relating to the code base that affect multiple projects; and ix. coordinating any marketing, events, or communications regarding the Project. 3. TSC Voting a. While the Project aims to operate as a consensus-based community, if any TSC decision requires a vote to move the Project forward, the voting members of the TSC will vote on a one vote per voting member basis. b. Quorum for TSC meetings requires at least fifty percent of all voting members of the TSC to be present. The TSC may continue to meet if quorum is not met but will be prevented from making any decisions at the meeting. c. Except as provided in Section 7.c. and 8.a, decisions by vote at a meeting require a majority vote of those in attendance, provided quorum is met. Decisions made by electronic vote without a meeting require a majority vote of all voting members of the TSC. d. In the event a vote cannot be resolved by the TSC, any voting member of the TSC may refer the matter to the Series Manager for assistance in reaching a resolution. 4. Compliance with Policies a. This Charter is subject to the Series Agreement for the Project and the Operating Agreement of LF Projects. Contributors will comply with the policies of LF Projects as may be adopted and amended by LF Projects, including, without limitation the policies listed at https://lfprojects.org/policies/. b. The TSC may adopt a code of conduct ("CoC") for the Project, which is subject to approval by the Series Manager. In the event that a Project-specific CoC has not been approved, the LF Projects Code of Conduct listed at https://lfprojects.org/policies will apply for all Collaborators in the Project. c. When amending or adopting any policy applicable to the Project, LF Projects will publish such policy, as to be amended or adopted, on its web site at least 30 days prior to such policy taking effect; provided, however, that in the case of any amendment of the Trademark Policy or Terms of Use of LF Projects, any such amendment is effective upon publication on LF Project's web site. d. All Collaborators must allow open participation from any individual or organization meeting the requirements for contributing under this Charter and any policies adopted for all Collaborators by the TSC, regardless of competitive interests. Put another way, the Project community must not seek to exclude any participant based on any criteria, requirement, or reason other than those that are reasonable and applied on a non-discriminatory basis to all Collaborators in the Project community. e. The Project will operate in a transparent, open, collaborative, and ethical manner at all times. The output of all Project discussions, proposals, timelines, decisions, and status should be made open and easily visible to all. Any potential violations of this requirement should be reported immediately to the Series Manager. 5. Community Assets a. LF Projects will hold title to all trade or service marks used by the Project ("Project Trademarks"), whether based on common law or registered rights. Project Trademarks will be transferred and assigned to LF Projects to hold on behalf of the Project. Any use of any Project Trademarks by Collaborators in the Project will be in accordance with the license from LF Projects and inure to the benefit of LF Projects. b. The Project will, as permitted and in accordance with such license from LF Projects, develop and own all Project GitHub and social media accounts, and domain name registrations created by the Project community. c. Under no circumstances will LF Projects be expected or required to undertake any action on behalf of the Project that is inconsistent with the tax-exempt status or purpose, as applicable, of LFP, Inc. or LF Projects, LLC. 6. General Rules and Operations. a. The Project will: i. engage in the work of the Project in a professional manner consistent with maintaining a cohesive community, while also maintaining the goodwill and esteem of LF Projects, LFP, Inc. and other partner organizations in the open source community; and ii. respect the rights of all trademark owners, including any branding and trademark usage guidelines. 7. Intellectual Property Policy a. Collaborators acknowledge that the copyright in all new contributions will be retained by the copyright holder as independent works of authorship and that no contributor or copyright holder will be required to assign copyrights to the Project. b. Except as described in Section 7.c., all contributions to the Project are subject to the following: i. All new inbound code contributions to the Project must be made using the Apache License, Version 2.0, available at https://www.apache.org/licenses/LICENSE-2.0 (the "Project License"). ii. All new inbound code contributions must also be accompanied by a Developer Certificate of Origin (http://developercertificate.org) sign-off in the source code system that is submitted through a TSC-approved contribution process which will bind the authorized contributor and, if not self-employed, their employer to the applicable license; iii. All outbound code will be made available under the Project License. iv. The Project may seek to integrate and contribute back to other open source projects ("Upstream Projects"). In such cases, the Project will conform to all license requirements of the Upstream Projects, including dependencies, leveraged by the Project. Upstream Project code contributions not stored within the Project's main code repository will comply with the contribution process and license terms for the applicable Upstream Project. c. The TSC may approve the use of an alternative license or licenses for inbound or outbound contributions on an exception basis. To request an exception, please describe the contribution, the alternative open source license(s), and the justification for using an alternative open source license for the Project. License exceptions must be approved by a two-thirds vote of the entire TSC. d. Contributed files should contain license information, such as SPDX short form identifiers, indicating the open source license or licenses pertaining to the file. 8. Amendments a. This charter may be amended by a two-thirds vote of the entire TSC and is subject to approval by LF Projects. ovn-25.09.0~git20250813.23884f5/Documentation/internals/committer-emeritus-status.rst000066400000000000000000000053561504532661100276770ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================== Emeritus Status for OVN Committers ================================== OVN committers are nominated and elected based on their impact on the OVN project. Over time, as committers' responsibilities change, some may become unable or uninterested in actively participating in project governance. Committer "emeritus" status provides a way for committers to take a leave of absence from OVN governance responsibilities. The following guidelines clarify the process around the emeritus status for committers: * A committer may choose to transition from active to emeritus, or from emeritus to active, by sending an email to the committers mailing list. * If a committer hasn't been heard from in 6 months, and does not respond to reasonable attempts to contact him or her, the other committers can vote as a majority to transition the committer from active to emeritus. (If the committer resurfaces, he or she can transition back to active by sending an email to the committers mailing list.) * Emeritus committers may stay on the committers mailing list to continue to follow any discussions there. * Emeritus committers do not nominate or vote in committer elections. From a governance perspective, they are equivalent to a non-committer. * Emeritus committers cannot merge patches to the OVN repository. * Emeritus committers will be listed in a separate section in the MAINTAINERS.rst file to continue to recognize their contributions to the project. Emeritus status does not replace the procedures for forcibly removing a committer. Note that just because a committer is not able to work on the project on a day-to-day basis, we feel they are still capable of providing input on the direction of the project. No committer should feel pressured to move themselves to this status. Again, it's just an option for those that do not currently have the time or interest. ovn-25.09.0~git20250813.23884f5/Documentation/internals/committer-grant-revocation.rst000066400000000000000000000331721504532661100300000ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ===================================== OVN Committer Grant/Revocation Policy ===================================== An OVN committer is a participant in the project with the ability to commit code directly to the main repository. Commit access grants a broad ability to affect the progress of the project as presented by its most important artifact, the code and related resources that produce working binaries of OVN As such it represents a significant level of trust in an individual's commitment to working with other committers and the community at large for the benefit of the project. It can not be granted lightly and, in the worst case, must be revocable if the trust placed in an individual was inappropriate. This document suggests guidelines for granting and revoking commit access. It is intended to provide a framework for evaluation of such decisions without specifying deterministic rules that wouldn't be sensitive to the nuance of specific situations. In the end the decision to grant or revoke committer privileges is a judgment call made by the existing set of committers. Granting Commit Access ---------------------- Granting commit access should be considered when a candidate has demonstrated the following in their interaction with the project: - Contribution of significant new features through the patch submission process where: - Submissions are free of obvious critical defects - Submissions do not typically require many iterations of improvement to be accepted - Consistent participation in code review of other's patches, including existing committers, with comments consistent with the overall project standards - Assistance to those in the community who are less knowledgeable through active participation in project forums such as the ovs-discuss mailing list. - Plans for sustained contribution to the project compatible with the project's direction as viewed by current committers. - Commitment to meet the expectations described in the "Expectations of Developer's with OVN Access" The process to grant commit access to a candidate is simple: - An existing committer nominates the candidate by sending an email to all existing committers with information substantiating the contributions of the candidate in the areas described above. - All existing committers discuss the pros and cons of granting commit access to the candidate in the email thread. - When the discussion has converged or a reasonable time has elapsed without discussion developing (e.g. a few business days) the nominator calls for a final decision on the candidate with a followup email to the thread. - Each committer may vote yes, no, or abstain by replying to the email thread. A failure to reply is an implicit abstention. - After votes from all existing committers have been collected or a reasonable time has elapsed for them to be provided (e.g. a couple of business days) the votes are evaluated. To be granted commit access the candidate must receive yes votes from a majority of the existing committers and zero no votes. Since a no vote is effectively a veto of the candidate it should be accompanied by a reason for the vote. - The nominator summarizes the result of the vote in an email to all existing committers. - If the vote to grant commit access passed, the candidate is contacted with an invitation to become a committer to the project which asks them to agree to the committer expectations documented on the project web site. - If the candidate agrees access is granted by setting up commit access to the repos on github. Revoking Commit Access ---------------------- When a committer behaves in a manner that other committers view as detrimental to the future of the project, it raises a delicate situation with the potential for the creation of division within the greater community. These situations should be handled with care. The process in this case is: - Discuss the behavior of concern with the individual privately and explain why you believe it is detrimental to the project. Stick to the facts and keep the email professional. Avoid personal attacks and the temptation to hypothesize about unknowable information such as the other's motivations. Make it clear that you would prefer not to discuss the behavior more widely but will have to raise it with other contributors if it does not change. Ideally the behavior is eliminated and no further action is required. If not, - Start an email thread with all committers, including the source of the behavior, describing the behavior and the reason it is detrimental to the project. The message should have the same tone as the private discussion and should generally repeat the same points covered in that discussion. The person whose behavior is being questioned should not be surprised by anything presented in this discussion. Ideally the wider discussion provides more perspective to all participants and the issue is resolved. If not, - Start an email thread with all committers except the source of the detrimental behavior requesting a vote on revocation of commit rights. Cite the discussion among all committers and describe all the reasons why it was not resolved satisfactorily. This email should be carefully written with the knowledge that the reasoning it contains may be published to the larger community to justify the decision. - Each committer may vote yes, no, or abstain by replying to the email thread. A failure to reply is an implicit abstention. - After all votes have been collected or a reasonable time has elapsed for them to be provided (e.g. a couple of business days) the votes are evaluated. For the request to revoke commit access for the candidate to pass it must receive yes votes from two thirds of the existing committers. - anyone that votes no must provide their reasoning, and - if the proposal passes then counter-arguments for the reasoning in no votes should also be documented along with the initial reasons the revocation was proposed. Ideally there should be no new counter-arguments supplied in a no vote as all concerns should have surfaced in the discussion before the vote. - The original person to propose revocation summarizes the result of the vote in an email to all existing committers excepting the candidate for removal. - If the vote to revoke commit access passes, access is removed and the candidate for revocation is informed of that fact and the reasons for it as documented in the email requesting the revocation vote. - Ideally the revoked committer peacefully leaves the community and no further action is required. However, there is a distinct possibility that he/she will try to generate support for his/her point of view within the larger community. In this case the reasoning for removing commit access as described in the request for a vote will be published to the community. Changing the Policy ------------------- The process for changing the policy is: - Propose the changes to the policy in an email to all current committers and request discussion. - After an appropriate period of discussion (a few days) update the proposal based on feedback if required and resend it to all current committers with a request for a formal vote. - After all votes have been collected or a reasonable time has elapsed for them to be provided (e.g. a couple of business days) the votes are evaluated. For the request to modify the policy to pass it must receive yes votes from two thirds of the existing committers. Template Emails =============== Nomination to Grant Commit Access --------------------------------- I would like to nominate *[candidate]* for commit access. I believe *[he/she]* has met the conditions for commit access described in the committer grant policy on the project web site in the following ways: *[list of requirements & evidence]* Please reply to all in this message thread with your comments and questions. If that discussion concludes favorably I will request a formal vote on the nomination in a few days. Vote to Grant Commit Access --------------------------- I nominated *[candidate]* for commit access on *[date]*. Having allowed sufficient time for discussion it's now time to formally vote on the proposal. Please reply to all in this thread with your vote of: YES, NO, or ABSTAIN. A failure to reply will be counted as an abstention. If you vote NO, by our policy you must include the reasons for that vote in your reply. The deadline for votes is *[date and time]*. If a majority of committers vote YES and there are zero NO votes commit access will be granted. Vote Results for Grant of Commit Access --------------------------------------- The voting period for granting to commit access to *[candidate]* initiated at *[date and time]* is now closed with the following results: YES: *[count of yes votes]* (*[% of voters]*) NO: *[count of no votes]* (*[% of voters]*) ABSTAIN: *[count of abstentions]* (*[% of voters]*) Based on these results commit access *[is/is NOT]* granted. Invitation to Accepted Committer -------------------------------- Due to your sustained contributions to the OVN project we would like to provide you with commit access to the project repository. Developers with commit access must agree to fulfill specific responsibilities described in the source repository: /Documentation/internals/committer-responsibilities.rst Please let us know if you would like to accept commit access and if so that you agree to fulfill these responsibilities. Once we receive your response we'll set up access. We're looking forward continuing to work together to advance the OVN project. Proposal to Revoke Commit Access for Detrimental Behavior --------------------------------------------------------- I regret that I feel compelled to propose revocation of commit access for *[candidate]*. I have privately discussed with *[him/her]* the following reasons I believe *[his/her]* actions are detrimental to the project and we have failed to come to a mutual understanding: *[List of reasons and supporting evidence]* Please reply to all in this thread with your thoughts on this proposal. I plan to formally propose a vote on the proposal on or after *[date and time]*. It is important to get all discussion points both for and against the proposal on the table during the discussion period prior to the vote. Please make it a high priority to respond to this proposal with your thoughts. Vote to Revoke Commit Access ---------------------------- I nominated *[candidate]* for revocation of commit access on *[date]*. Having allowed sufficient time for discussion it's now time to formally vote on the proposal. Please reply to all in this thread with your vote of: YES, NO, or ABSTAIN. A failure to reply will be counted as an abstention. If you vote NO, by our policy you must include the reasons for that vote in your reply. The deadline for votes is *[date and time]*. If 2/3rds of committers vote YES commit access will be revoked. The following reasons for revocation have been given in the original proposal or during discussion: *[list of reasons to remove access]* The following reasons for retaining access were discussed: *[list of reasons to retain access]* The counter-argument for each reason for retaining access is: *[list of counter-arguments for retaining access]* Vote Results for Revocation of Commit Access -------------------------------------------- The voting period for revoking the commit access of *[candidate]* initiated at *[date and time]* is now closed with the following results: - YES: *[count of yes votes]* (*[% of voters]*) - NO: *[count of no votes]* (*[% of voters]*) - ABSTAIN: *[count of abstentions]* (*[% of voters]*) Based on these results commit access *[is/is NOT]* revoked. The following reasons for retaining commit access were proposed in NO votes: *[list of reasons]* The counter-arguments for each of these reasons are: *[list of counter-arguments]* Notification of Commit Revocation for Detrimental Behavior ---------------------------------------------------------- After private discussion with you and careful consideration of the situation, the other committers to the OVN project have concluded that it is in the best interest of the project that your commit access to the project repositories be revoked and this has now occurred. The reasons for this decision are: *[list of reasons for removing access]* While your goals and those of the project no longer appear to be aligned we greatly appreciate all the work you have done for the project and wish you continued success in your future work. ovn-25.09.0~git20250813.23884f5/Documentation/internals/committer-responsibilities.rst000066400000000000000000000125061504532661100301030ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================================ Expectations for Developers with OVN Repo Access ================================================ Pre-requisites -------------- Be familiar with the guidelines and standards defined in :doc:`contributing/index`. Review ------ Code (yours or others') must be reviewed publicly (by you or others) before you push it to the repository. With one exception (see below), every change needs at least one review. If one or more people know an area of code particularly well, code that affects that area should ordinarily get a review from one of them. The riskier, more subtle, or more complicated the change, the more careful the review required. When a change needs careful review, use good judgment regarding the quality of reviews. If a change adds 1000 lines of new code, and a review posted 5 minutes later says just "Looks good," then this is probably not a quality review. (The size of a change is correlated with the amount of care needed in review, but it is not strictly tied to it. A search and replace across many files may not need much review, but one-line optimization changes can have widespread implications.) Your own small changes to fix a recently broken build ("make") or tests ("make check"), that you believe to be visible to a large number of developers, may be checked in without review. If you are not sure, ask for review. If you do push a build fix without review, send the patch to ovs-dev afterward as usual, indicating in the email that you have already pushed it. Regularly review submitted code in areas where you have expertise. Consider reviewing other code as well. Git conventions --------------- Do not push merge commits to the Git repository without prior discussion on ovs-dev. If you apply a change (yours or another's) then it is your responsibility to handle any resulting problems, especially broken builds and other regressions. If it is someone else's change, then you can ask the original submitter to address it. Regardless, you need to ensure that the problem is fixed in a timely way. The definition of "timely" depends on the severity of the problem. If a bug is present on main and other branches, fix it on main first, then backport the fix to other branches. Straightforward backports do not require additional review (beyond that for the fix on main). Feature development should be done only on main. Occasionally it makes sense to add a feature to the most recent release branch, before the first actual release of that branch. These should be handled in the same way as bug fixes, that is, first implemented on main and then backported. Keep the authorship of a commit clear by maintaining a correct list of "Signed-off-by:"s. If a confusing situation comes up, as it occasionally does, bring it up on the mailing list. If you explain the use of "Signed-off-by:" to a new developer, explain not just how but why, since the intended meaning of "Signed-off-by:" is more important than the syntax. As part of your explanation, quote or provide a URL to the Developer's Certificate of Origin in :doc:`contributing/submitting-patches`. Use Reported-by: and Tested-by: tags in commit messages to indicate the source of a bug report. Keep the ``AUTHORS.rst`` file up to date. Pre-Push Hook ------------- The following script can be helpful because it provides an extra chance to check for mistakes while pushing to the main branch. If you would like to use it, install it as ``hooks/pre-push`` in your ``.git`` directory and make sure to mark it as executable with ``chmod +x``. For maximum utility, make sure ``checkpatch.py`` is in ``$PATH``: .. code-block:: bash #! /bin/bash remote=$1 case $remote in ovs|ovn|origin) ;; *) exit 0 ;; esac while read local_ref local_sha1 remote_ref remote_sha1; do case $remote_ref in refs/heads/main) n=0 while read sha do n=$(expr $n + 1) git log -1 $sha echo checkpatch.py -1 $sha done < /dev/null; then : else exit 1 fi ;; esac done exit 0 ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/000077500000000000000000000000001504532661100244645ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/backporting-patches.rst000066400000000000000000000162331504532661100311530ustar00rootroot00000000000000.. Copyright (c) 2017 Nicira, Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================== Backporting patches =================== .. note:: This is an advanced topic for developers and maintainers. Readers should familiarize themselves with building and running OVN, with the git tool, and with the OVN patch submission process. The backporting of patches from one git tree to another takes multiple forms within OVN, but is broadly applied in the following fashion: - Contributors submit their proposed changes to the latest development branch - Contributors and maintainers provide feedback on the patches - When the change is satisfactory, maintainers apply the patch to the development branch. - Maintainers backport changes from a development branch to release branches. The development branch is `main` in the OVN repository. Patches are applied first to this branch, then to the most recent `branch-X.Y`, then earlier `branch-X.Z`, and so on. The most common kind of patch in this category is a bugfix which affects main and other branches. Backport Policy --------------- Patches which are fixing bugs should be considered for backporting from `main` to release branches. OVN contributors submit their patches targeted to the `main` branch, using the ``Fixes`` tag desribed in :doc:`submitting-patches`. The maintainer first applies the patch to `main`, then backports the patch to each older affected tree, as far back as it goes or at least to all currently supported branches. This is usually each branch back to the most recent LTS release branch. If the fix only affects a particular branch and not `main`, contributors should submit the change with the target branch listed in the subject line of the patch. Contributors should list all versions that the bug affects. The ``git format-patch`` argument ``--subject-prefix`` may be used when posting the patch, for example: :: $ git format-patch -1 --subject-prefix="PATCH ovn branch-21.06" If a maintainer is backporting a change to older branches and the backport is not a trivial cherry-pick, then the maintainer may opt to submit the backport for the older branch on the mailing list for further review. This should be done in the same manner as described above. Supported Versions ~~~~~~~~~~~~~~~~~~ As documented in :doc:`../release-process`, standard term support branches receive regular releases for a year, and LTS branches receive regular releases for two years, plus an additional year of critical and security fixes. To make things easy, maintainers should simply backport all bugfixes to the previous four branches before main. This is guaranteed to get the fix into all supported standard-support branches as well as the current LTS branch. This will mean that maintainers will backport bugfixes to branches representing branches that are not currently supported. Critical and security fixes should be handled differently. Maintainers should determine what is the oldest LTS branch that currently is supported for critical and security fixes. Maintainers should backport these fixes to all branches between main and that LTS branch. This will mean that maintainers will backport critical and security fixes into branches for which no further releases are being made. The reason for backporting fixes into unsupported branches is twofold: - Backporting bugfixes into unsupported branches likely makes it easier to backport critical and security fixes into older branches when necessary. - Backporting critical and security fixes into unsupported branches allows for users that are not ready to upgrade to a version in a supported branch to continue using the branch tip until they are ready to fully upgrade. Example +++++++ Consider the following release timeline. +---------+----------+--------------+ | Branch | Date | Release Type | +---------+----------+--------------+ | 24.03 | Mar 2024 | LTS | +---------+----------+--------------+ | 24.09 | Sep 2024 | Standard | +---------+----------+--------------+ | 25.03 | Mar 2025 | Standard | +---------+----------+--------------+ | 25.09 | Sep 2025 | Standard | +---------+----------+--------------+ | 26.03 | Mar 2026 | LTS | +---------+----------+--------------+ | 26.09 | Sep 2026 | Standard | +---------+----------+--------------+ In our hypothetical world it is October 2026, so the current status of each release is: +---------+------------------------------+ | Branch | Support Status | +---------+------------------------------+ | 24.03 | Critical/Security fixes only | +---------+------------------------------+ | 24.09 | Unsupported since Sep 2025 | +---------+------------------------------+ | 25.03 | Unsupported since Mar 2026 | +---------+------------------------------+ | 25.09 | Unsupported since Sep 2026 | +---------+------------------------------+ | 26.03 | Supported | +---------+------------------------------+ | 26.09 | Supported | +---------+------------------------------+ Let's say that a bug fix is committed to main. Our policy would be to backport the fix to 26.09, 26.03, 25.09, and 25.03. The fix will eventually appear in releases of 26.03 and 26.09. Even though the fix is in the development branches for 25.03 and 25.09, the fix will never appear in a release. Now let's say that a security issue is committed to main. Our policy would be to backport the fix to 24.03, 24.09, 25.03, 25.09, 26.03, and 26.09. 24.03 is the oldest LTS branch that still is receiving critical and security fixes, so we backport the fix to all branches between main and that branch. The security fix will appear in releases of 24.03, 26.03, and 26.09. The security fix will be present in the 24.09, 25.03, and 25.09 development branches, but will never appear in a release. Submission ~~~~~~~~~~ Once the patches are all assembled and working on the OVN tree, they need to be formatted again using ``git format-patch``. The contents of a backport should be equivalent to the changes made by the original patch; explain any variations from the original patch in the commit message - For instance if you rolled in a bugfix. Reviewers will verify that the changes made by the backport patch are the same as the changes made in the original commit which the backport is based upon. Patch submission should otherwise follow the regular steps described in :doc:`submitting-patches`. ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/coding-style.rst000066400000000000000000000520431504532661100276230ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================ OVN Coding Style ================ This file describes the coding style used in C files in the OVN distribution. The following GNU indent options approximate this style. :: -npro -bad -bap -bbb -br -blf -brs -cdw -ce -fca -cli0 -npcs -i4 -l79 \ -lc79 -nbfda -nut -saf -sai -saw -sbi4 -sc -sob -st -ncdb -pi4 -cs -bs \ -di1 -lp -il0 -hnl .. _basics: Basics ------ - Limit lines to 79 characters. - Use form feeds (control+L) to divide long source files into logical pieces. A form feed should appear as the only character on a line. - Do not use tabs for indentation. - Avoid trailing spaces on lines. .. _naming: Naming ------ - Use names that explain the purpose of a function or object. - Use underscores to separate words in an identifier: ``multi_word_name``. - Use lowercase for most names. Use uppercase for macros, macro parameters, and members of enumerations. - Give arrays names that are plural. - Pick a unique name prefix (ending with an underscore) for each module, and apply that prefix to all of that module's externally visible names. Names of macro parameters, struct and union members, and parameters in function prototypes are not considered externally visible for this purpose. - Do not use names that begin with ``_``. If you need a name for "internal use only", use ``__`` as a suffix instead of a prefix. - Avoid negative names: ``found`` is a better name than ``not_found``. - In names, a ``size`` is a count of bytes, a ``length`` is a count of characters. A buffer has size, but a string has length. The length of a string does not include the null terminator, but the size of the buffer that contains the string does. .. _comments: Comments -------- Comments should be written as full sentences that start with a capital letter and end with a period. Put two spaces between sentences. Write block comments as shown below. You may put the ``/*`` and ``*/`` on the same line as comment text if you prefer. :: /* * We redirect stderr to /dev/null because we often want to remove all * traffic control configuration on a port so its in a known state. If * this done when there is no such configuration, tc complains, so we just * always ignore it. */ Each function and each variable declared outside a function, and each struct, union, and typedef declaration should be preceded by a comment. See functions_ below for function comment guidelines. Each struct and union member should each have an inline comment that explains its meaning. structs and unions with many members should be additionally divided into logical groups of members by block comments, e.g.: :: /* An event that will wake the following call to poll_block(). */ struct poll_waiter { /* Set when the waiter is created. */ struct ovs_list node; /* Element in global waiters list. */ int fd; /* File descriptor. */ short int events; /* Events to wait for (POLLIN, POLLOUT). */ poll_fd_func *function; /* Callback function, if any, or null. */ void *aux; /* Argument to callback function. */ struct backtrace *backtrace; /* Event that created waiter, or null. */ /* Set only when poll_block() is called. */ struct pollfd *pollfd; /* Pointer to element of the pollfds array (null if added from a callback). */ }; Use ``XXX`` or ``FIXME`` comments to mark code that needs work. Don't use ``//`` comments. Don't comment out or ``#if 0`` out code. Just remove it. The code that was there will still be in version control history. .. _functions: Functions --------- Put the return type, function name, and the braces that surround the function's code on separate lines, all starting in column 0. Before each function definition, write a comment that describes the function's purpose, including each parameter, the return value, and side effects. References to argument names should be given in single-quotes, e.g. ``'arg'``. The comment should not include the function name, nor need it follow any formal structure. The comment does not need to describe how a function does its work, unless this information is needed to use the function correctly (this is often better done with comments *inside* the function). Simple static functions do not need a comment. Within a file, non-static functions should come first, in the order that they are declared in the header file, followed by static functions. Static functions should be in one or more separate pages (separated by form feed characters) in logical groups. A commonly useful way to divide groups is by "level", with high-level functions first, followed by groups of progressively lower-level functions. This makes it easy for the program's reader to see the top-down structure by reading from top to bottom. All function declarations and definitions should include a prototype. Empty parentheses, e.g. ``int foo();``, do not include a prototype (they state that the function's parameters are unknown); write ``void`` in parentheses instead, e.g. ``int foo(void);``. Prototypes for static functions should either all go at the top of the file, separated into groups by blank lines, or they should appear at the top of each page of functions. Don't comment individual prototypes, but a comment on each group of prototypes is often appropriate. In the absence of good reasons for another order, the following parameter order is preferred. One notable exception is that data parameters and their corresponding size parameters should be paired. 1. The primary object being manipulated, if any (equivalent to the ``this`` pointer in C++). 2. Input-only parameters. 3. Input/output parameters. 4. Output-only parameters. 5. Status parameter. Example: :: ``` /* Stores the features supported by 'netdev' into each of '*current', * '*advertised', '*supported', and '*peer' that are non-null. Each value * is a bitmap of "enum ofp_port_features" bits, in host byte order. * Returns 0 if successful, otherwise a positive errno value. On failure, * all of the passed-in values are set to 0. */ int netdev_get_features(struct netdev *netdev, uint32_t *current, uint32_t *advertised, uint32_t *supported, uint32_t *peer) { ... } ``` Functions that destroy an instance of a dynamically-allocated type should accept and ignore a null pointer argument. Code that calls such a function (including the C standard library function ``free()``) should omit a null-pointer check. We find that this usually makes code easier to read. Functions in ``.c`` files should not normally be marked ``inline``, because it does not usually help code generation and it does suppress compiler warnings about unused functions. (Functions defined in ``.h`` usually should be marked ``inline``.) .. _function prototypes: Function Prototypes ------------------- Put the return type and function name on the same line in a function prototype: :: static const struct option_class *get_option_class(int code); Omit parameter names from function prototypes when the names do not give useful information, e.g.: :: int netdev_get_mtu(const struct netdev *, int *mtup); Statements ---------- Indent each level of code with 4 spaces. Use BSD-style brace placement: :: if (a()) { b(); d(); } Put a space between ``if``, ``while``, ``for``, etc. and the expressions that follow them. Enclose single statements in braces: :: if (a > b) { return a; } else { return b; } Use comments and blank lines to divide long functions into logical groups of statements. Avoid assignments inside ``if`` and ``while`` conditions. Do not put gratuitous parentheses around the expression in a return statement, that is, write ``return 0;`` and not ``return(0);`` Write only one statement per line. Indent ``switch`` statements like this: :: switch (conn->state) { case S_RECV: error = run_connection_input(conn); break; case S_PROCESS: error = 0; break; case S_SEND: error = run_connection_output(conn); break; default: OVS_NOT_REACHED(); } ``switch`` statements with very short, uniform cases may use an abbreviated style: :: switch (code) { case 200: return "OK"; case 201: return "Created"; case 202: return "Accepted"; case 204: return "No Content"; default: return "Unknown"; } Use ``for (;;)`` to write an infinite loop. In an ``if/else`` construct where one branch is the "normal" or "common" case and the other branch is the "uncommon" or "error" case, put the common case after the ``if``, not the ``else``. This is a form of documentation. It also places the most important code in sequential order without forcing the reader to visually skip past less important details. (Some compilers also assume that the ``if`` branch is the more common case, so this can be a real form of optimization as well.) Return Values ------------- For functions that return a success or failure indication, prefer one of the following return value conventions: - An ``int`` where ``0`` indicates success and a positive errno value indicates a reason for failure. - A ``bool`` where ``true`` indicates success and ``false`` indicates failure. Macros ------ Don't define an object-like macro if an enum can be used instead. Don't define a function-like macro if a ``static inline`` function can be used instead. If a macro's definition contains multiple statements, enclose them with ``do { ... } while (0)`` to allow them to work properly in all syntactic circumstances. Do use macros to eliminate the need to update different parts of a single file in parallel, e.g. a list of enums and an array that gives the name of each enum. For example: :: /* Logging importance levels. */ #define VLOG_LEVELS \ VLOG_LEVEL(EMER, LOG_ALERT) \ VLOG_LEVEL(ERR, LOG_ERR) \ VLOG_LEVEL(WARN, LOG_WARNING) \ VLOG_LEVEL(INFO, LOG_NOTICE) \ VLOG_LEVEL(DBG, LOG_DEBUG) enum vlog_level { #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) VLL_##NAME, VLOG_LEVELS #undef VLOG_LEVEL VLL_N_LEVELS }; /* Name for each logging level. */ static const char *level_names[VLL_N_LEVELS] = { #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) #NAME, VLOG_LEVELS #undef VLOG_LEVEL }; Thread Safety Annotations ------------------------- Use the macros in ``lib/compiler.h`` to annotate locking requirements. For example: :: static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER; static struct ovs_rwlock rwlock = OVS_RWLOCK_INITIALIZER; void function_require_plain_mutex(void) OVS_REQUIRES(mutex); void function_require_rwlock(void) OVS_REQ_RDLOCK(rwlock); Pass lock objects, not their addresses, to the annotation macros. (Thus we have ``OVS_REQUIRES(mutex)`` above, not ``OVS_REQUIRES(&mutex)``.) .. _source files: Source Files ------------ Each source file should state its license in a comment at the very top, followed by a comment explaining the purpose of the code that is in that file. The comment should explain how the code in the file relates to code in other files. The goal is to allow a programmer to quickly figure out where a given module fits into the larger system. The first non-comment line in a ``.c`` source file should be: :: #include ``#include`` directives should appear in the following order: 1. ``#include `` 2. The module's own headers, if any. Including this before any other header (besides ) ensures that the module's header file is self-contained (see `header files`_ below). 3. Standard C library headers and other system headers, preferably in alphabetical order. (Occasionally one encounters a set of system headers that must be included in a particular order, in which case that order must take precedence.) 4. OVN headers, in alphabetical order. Use ``""``, not ``<>``, to specify OVN header names. .. _header files: Header Files ------------ Each header file should start with its license, as described under `source files`_ above, followed by a "header guard" to make the header file idempotent, like so: :: #ifndef NETDEV_H #define NETDEV_H 1 ... #endif /* netdev.h */ Header files should be self-contained; that is, they should ``#include`` whatever additional headers are required, without requiring the client to ``#include`` them for it. Don't define the members of a struct or union in a header file, unless client code is actually intended to access them directly or if the definition is otherwise actually needed (e.g. inline functions defined in the header need them). Similarly, don't ``#include`` a header file just for the declaration of a struct or union tag (e.g. just for ``struct ;``). Just declare the tag yourself. This reduces the number of header file dependencies. Types ----- Use typedefs sparingly. Code is clearer if the actual type is visible at the point of declaration. Do not, in general, declare a typedef for a ``struct``, ``union``, or ``enum``. Do not declare a typedef for a pointer type, because this can be very confusing to the reader. A function type is a good use for a typedef because it can clarify code. The type should be a function type, not a pointer-to-function type. That way, the typedef name can be used to declare function prototypes. (It cannot be used for function definitions, because that is explicitly prohibited by C89 and C99.) You may assume that ``char`` is exactly 8 bits and that ``int`` and ``long`` are at least 32 bits. Don't assume that ``long`` is big enough to hold a pointer. If you need to cast a pointer to an integer, use ``intptr_t`` or ``uintptr_t`` from . Use the ``int_t`` and ``uint_t`` types from for exact-width integer types. Use the ``PRId``, ``PRIu``, and ``PRIx`` macros from for formatting them with ``printf()`` and related functions. For compatibility with antique ``printf()`` implementations: - Instead of ``"%zu"``, use ``"%"PRIuSIZE``. - Instead of ``"%td"``, use ``"%"PRIdPTR``. - Instead of ``"%ju"``, use ``"%"PRIuMAX``. Other variants exist for different radixes. For example, use ``"%"PRIxSIZE`` instead of ``"%zx"`` or ``"%x"`` instead of ``"%hhx"``. Also, instead of ``"%hhd"``, use ``"%d"``. Be cautious substituting ``"%u"``, ``"%x"``, and ``"%o"`` for the corresponding versions with ``"hh"``: cast the argument to unsigned char if necessary, because ``printf("%hhu", -1)`` prints ``255`` but ``printf("%u", -1)`` prints ``4294967295``. Use bit-fields sparingly. Do not use bit-fields for layout of network protocol fields or in other circumstances where the exact format is important. Declare bit-fields to be signed or unsigned integer types or ``_Bool`` (aka ``bool``). Do *not* declare bit-fields of type ``int``: C99 allows these to be either signed or unsigned according to the compiler's whim. (A 1-bit bit-field of type ``int`` may have a range of ``-1...0``!) Try to order structure members such that they pack well on a system with 2-byte ``short``, 4-byte ``int``, and 4- or 8-byte ``long`` and pointer types. Prefer clear organization over size optimization unless you are convinced there is a size or speed benefit. Pointer declarators bind to the variable name, not the type name. Write ``int *x``, not ``int* x`` and definitely not ``int * x``. Expressions ----------- Put one space on each side of infix binary and ternary operators: :: * / % + - << >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= Avoid comma operators. Do not put any white space around postfix, prefix, or grouping operators: :: () [] -> . ! ~ ++ -- + - * & Exception 1: Put a space after (but not before) the "sizeof" keyword. Exception 2: Put a space between the ``()`` used in a cast and the expression whose type is cast: ``(void *) 0``. Break long lines before the ternary operators ``?`` and ``:``, rather than after them, e.g. :: return (out_port != VIGP_CONTROL_PATH ? alpheus_output_port(dp, skb, out_port) : alpheus_output_control(dp, skb, fwd_save_skb(skb), VIGR_ACTION)); Parenthesize the operands of ``&&`` and ``||`` if operator precedence makes it necessary, or if the operands are themselves expressions that use ``&&`` and ``||``, but not otherwise. Thus:: if (rule && (!best || rule->priority > best->priority)) { best = rule; } but:: if (!isdigit((unsigned char)s[0]) || !isdigit((unsigned char)s[1]) || !isdigit((unsigned char)s[2])) { printf("string %s does not start with 3-digit code\n", s); } Do parenthesize a subexpression that must be split across more than one line, e.g.:: *idxp = ((l1_idx << PORT_ARRAY_L1_SHIFT) | (l2_idx << PORT_ARRAY_L2_SHIFT) | (l3_idx << PORT_ARRAY_L3_SHIFT)); Breaking a long line after a binary operator gives its operands a more consistent look, since each operand has the same horizontal position. This makes the end-of-line position a good choice when the operands naturally resemble each other, as in the previous two examples. On the other hand, breaking before a binary operator better draws the eye to the operator, which can help clarify code by making it more obvious what's happening, such as in the following example:: if (!ctx.freezing && xbridge->has_in_band && in_band_must_output_to_local_port(flow) && !actions_output_to_local_port(&ctx)) { Thus, decide whether to break before or after a binary operator separately in each situation, based on which of these factors appear to be more important. Try to avoid casts. Don't cast the return value of malloc(). The ``sizeof`` operator is unique among C operators in that it accepts two very different kinds of operands: an expression or a type. In general, prefer to specify an expression, e.g. ``int *x = xmalloc(sizeof *x);``. When the operand of ``sizeof`` is an expression, there is no need to parenthesize that operand, and please don't. Use the ``ARRAY_SIZE`` macro from ``lib/util.h`` to calculate the number of elements in an array. When using a relational operator like ``<`` or ``==``, put an expression or variable argument on the left and a constant argument on the right, e.g. ``x == 0``, *not* ``0 == x``. Blank Lines ----------- Put one blank line between top-level definitions of functions and global variables. C DIALECT --------- Most C99 features are OK because they are widely implemented: - Flexible array members (e.g. ``struct { int foo[]; }``). - ``static inline`` functions (but no other forms of ``inline``, for which GCC and C99 have differing interpretations). - ``long long`` - ``bool`` and ````, but don't assume that ``bool`` or ``_Bool`` can only take on the values ``0`` or ``1``, because this behavior can't be simulated on C89 compilers. Also, don't assume that a conversion to ``bool`` or ``_Bool`` follows C99 semantics, i.e. use ``(bool) (some_value != 0)`` rather than ``(bool) some_value``. The latter might produce unexpected results on non-C99 environments. For example, if ``bool`` is implemented as a typedef of char and ``some_value = 0x10000000``. - Designated initializers (e.g. ``struct foo foo = { .a = 1 };`` and ``int a[] = { [2] = 5 };``). - Mixing of declarations and code within a block. Favor positioning that allows variables to be initialized at their point of declaration. - Use of declarations in iteration statements (e.g. ``for (int i = 0; i < 10; i++)``). - Use of a trailing comma in an enum declaration (e.g. ``enum { x = 1, };``). As a matter of style, avoid ``//`` comments. Avoid using GCC or Clang extensions unless you also add a fallback for other compilers. You can, however, use C99 features or GCC extensions also supported by Clang in code that compiles only on GNU/Linux (such as ``lib/netdev-linux.c``), because GCC is the system compiler there. Python ------ When introducing new Python code, try to follow Python's `PEP 8 `__ style. Consider running the ``pep8`` or ``flake8`` tool against your code to find issues. ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/documentation-style.rst000066400000000000000000000256251504532661100312370ustar00rootroot00000000000000.. Copyright (c) 2016 Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================= OVN Documentation Style ======================= This file describes the documentation style used in all documentation found in OVN. Documentation includes any documents found in ``Documentation`` along with any ``README``, ``MAINTAINERS``, or generally ``rst`` suffixed documents found in the project tree. reStructuredText vs. Sphinx --------------------------- `reStructuredText (rST)`__ is the syntax, while `Sphinx`__ is a documentation generator. Sphinx introduces a number of extensions to rST, like the ``:ref:`` role, which can and should be used in documentation, but these will not work correctly on GitHub. As such, these extensions should not be used in any documentation in the root level, such as the ``README``. __ http://docutils.sourceforge.net/rst.html __ http://www.sphinx-doc.org/ rST Conventions --------------- Basics ~~~~~~ Many of the basic documentation guidelines match those of the :doc:`coding-style`. - Use reStructuredText (rST) for all documentation. Sphinx extensions can be used, but only for documentation in the ``Documentation`` folder. - Limit lines at 79 characters. .. note:: An exception to this rule is text within code-block elements that cannot be wrapped and links within references. - Use spaces for indentation. - Match indentation levels. A change in indentation level usually signifies a change in content nesting, by either closing the existing level or introducing a new level. - Avoid trailing spaces on lines. - Include a license (see this file) in all docs. - Most importantly, always build and display documentation before submitting changes! Docs aren't unit testable, so visible inspection is necessary. File Names ~~~~~~~~~~ - Use hyphens as space delimiters. For example: ``my-readme-document.rst`` .. note:: An exception to this rule is any man pages, which take an trailing number corresponding to the number of arguments required. This number is preceded by an underscore. - Use lowercase filenames. .. note:: An exception to this rule is any documents found in the root-level of the project. Titles ~~~~~~ - Use the following headers levels. | ``=======`` Heading 0 (reserved for the title in a document) | ``-------`` Heading 1 | ``~~~~~~~`` Heading 2 | ``+++++++`` Heading 3 | ``'''''''`` Heading 4 .. note:: Avoid using lower heading levels by rewriting and reorganizing the information. - Under- and overlines should be of the same length as that of the heading text. - Use "title case" for headers. Code ~~~~ - Use ``::`` to prefix code. - Don't use syntax highlighting such as ``.. highlight:: `` or ``code-block:: `` because it depends on external ``pygments`` library. - Prefix commands with ``$``. - Where possible, include fully-working snippets of code. If there pre-requisites, explain what they are and how to achieve them. Admonitions ~~~~~~~~~~~ - Use admonitions to call attention to important information.:: .. note:: This is a sample callout for some useful tip or trick. Example admonitions include: ``warning``, ``important``, ``note``, ``tip`` or ``seealso``. - Use notes sparingly. Avoid having more than one per subsection. Tables ~~~~~~ - Use either graphic tables, list tables or CSV tables. Graphic tables ++++++++++++++ :: .. table:: OVS-Linux kernel compatibility ============ ============== Open vSwitch Linux kernel ============ ============== 1.4.x 2.6.18 to 3.2 1.5.x 2.6.18 to 3.2 1.6.x 2.6.18 to 3.2 ============ ============== :: .. table:: OVS-Linux kernel compatibility +--------------+---------------+ | Open vSwitch | Linux kernel | +==============+===============+ | 1.4.x | 2.6.18 to 3.2 | +--------------+---------------+ | 1.5.x | 2.6.18 to 3.2 | +--------------+---------------+ | 1.6.x | 2.6.18 to 3.2 | +--------------+---------------+ .. note:: The ``table`` role - ``.. table:: `` - can be safely omitted. List tables +++++++++++ :: .. list-table:: OVS-Linux kernel compatibility :widths: 10 15 :header-rows: 1 * - Open vSwitch - Linux kernel * - 1.4.x - 2.6.18 to 3.2 * - 1.5.x - 2.6.18 to 3.2 * - 1.6.x - 2.6.18 to 3.2 CSV tables ++++++++++ :: .. csv-table:: OVS-Linux kernel compatibility :header: Open vSwitch, Linux kernel :widths: 10 15 1.4.x, 2.6.18 to 3.2 1.5.x, 2.6.18 to 3.2 1.6.x, 2.6.18 to 3.2 Cross-referencing ~~~~~~~~~~~~~~~~~ - To link to an external file or document, include as a link.:: Here's a `link `__ to the Open vSwitch website. Here's a `link`_ in reference style. .. _link: http://openvswitch.org - You can also use citations.:: Refer to the Open vSwitch documentation [1]_. References ---------- .. [1]: http://openvswitch.org - To cross-reference another doc, use the ``doc`` role.:: Here is a link to the :doc:`/README.rst` .. note:: This is a Sphinx extension. Do not use this in any top-level documents. - To cross-reference an arbitrary location in a doc, use the ``ref`` role.:: .. _sample-crossref Title ~~~~~ Hello, world. Another Title ~~~~~~~~~~~~~ Here is a cross-reference to :ref:`sample-crossref`. .. note:: This is a Sphinx extension. Do not use this in any top-level documents. Figures and Other Media ~~~~~~~~~~~~~~~~~~~~~~~ - All images should be in PNG format and compressed where possible. For PNG files, use OptiPNG and AdvanceCOMP's ``advpng``: :: $ optipng -o7 -zm1-9 -i0 -strip all $ advpng -z4 - Any ASCII text "images" should be included in code-blocks to preserve formatting - Include other reStructuredText verbatim in a current document Comments ~~~~~~~~ - Comments are indicated by means of the ``..`` marker.:: .. TODO(stephenfin) This section needs some work. This TODO will not appear in the final generated document, however. Man Pages --------- In addition to the above, man pages have some specific requirements: - You **must** define the following sections: - Synopsis - Description - Options Note that `NAME` is not included - this is automatically generated by Sphinx and should not be manually defined. Also note that these do not need to be uppercase - Sphinx will do this automatically. Additional sections are allowed. Refer to `man-pages(8)` for information on the sections generally allowed. - You **must not** define a `NAME` section. See above. - The `OPTIONS` section must describe arguments and options using the `program`__ and `option`__ directives. This ensures the output is formatted correctly and that you can cross-reference various programs and commands from the documentation. For example:: .. program:: ovs-do-something .. option:: -f, --force Force the operation .. option:: -b , --bridge Name or ID of bridge .. important:: Option argument names should be enclosed in angle brackets, as above. - Any references to the application or any other OVN application must be marked up using the `program` role. This allows for easy linking in the HTML output and correct formatting in the man page output. For example:: To do something, run :program:`ovs-do-something`. - The man page must be included in the list of man page documents found in `conf.py`__ Refer to existing man pages, such as :doc:`/ref/ovn-sim.1` for a worked example. __ http://www.sphinx-doc.org/en/stable/domains.html#directive-program __ http://www.sphinx-doc.org/en/stable/domains.html#directive-option __ http://www.sphinx-doc.org/en/stable/config.html#confval-man_pages Writing Style ------------- Follow these guidelines to ensure readability and consistency of the Open vSwitch documentation. These guidelines are based on the `/*IBM Style Guide/* `__. - Use standard US English Use a spelling and grammar checking tool as necessary. - Expand initialisms and acronyms on first usage. Commonly used terms like CPU or RAM are allowed. .. list-table:: :header-rows: 1 * - Do not use - Do use * - OVS is a virtual switch. OVS has... - Open vSwitch (OVS) is a virtual switch. OVS has... * - The VTEP emulator is... - The Virtual Tunnel Endpoint (VTEP) emulator is... - Write in the active voice The subject should do the verb's action, rather than be acted upon. .. list-table:: :header-rows: 1 * - Do not use - Do use * - A bridge is created by you - Create a bridge - Write in the present tense .. list-table:: :header-rows: 1 * - Do not use - Do use * - Once the bridge is created, you can create a port - Once the bridge is created, create a port - Write in second person .. list-table:: :header-rows: 1 * - Do not use - Do use * - To create a bridge, the user runs: - To create a bridge, run: - Keep sentences short and concise - Eliminate needless politeness Avoid "please" and "thank you" Helpful Tools ------------- There are a number of tools, online and offline, which can be used to preview documents are you edit them: - `rst.ninjs.org `__ An online rST editor/previewer - `ReText `__ A simple but powerful editor for Markdown and reStructuredText. ReText is written in Python. - `restview `__ A viewer for ReStructuredText documents that renders them on the fly. Useful Links ------------ - `Quick reStructuredText `__ - `Sphinx Documentation `__ ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/inclusive-language.rst000066400000000000000000000042271504532661100310050ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================== Inclusive Language ================== In order to help facilitate an inclusive environment in the OVN community we recognise the role of language in framing our communication with each other. It is important that terms that may exclude people through racial, cultural or other bias, are avoided as they may make people feel excluded. We recognise that this is subjective, and to some extent is a journey. But we also recognise that we cannot begin that journey without taking positive action. To this end OVN is adopting the practice of an inclusive word list, which helps to guide the use of language within the project. .. _word list: Word List --------- The intent of this document is to formally document the acceptance of a inclusive word list by OVN. Accordingly, this document specifies use of the use the `Inclusive Naming Word List `__ v1.0 (the word list) for OVN. The adoption of the word list intended that this act as a guide for developers creating patches to the OVN repository, including both source code and documentation. And to aid maintainers in their role of shepherding changes into the repository. Further steps to align usage of language in OVN, including clarification of application of the word list, to new and existing work, may follow. ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/index.rst000066400000000000000000000021541504532661100263270ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================== Contributing to OVN =================== The below guides provide information on contributing to OVN itself. .. toctree:: :maxdepth: 2 submitting-patches inclusive-language backporting-patches coding-style documentation-style ovn-25.09.0~git20250813.23884f5/Documentation/internals/contributing/submitting-patches.rst000066400000000000000000000440751504532661100310420ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================== Submitting Patches ================== Send changes to OVN as patches to dev@openvswitch.org. One patch per email. More details are included below. If you are using Git, then `git format-patch` takes care of most of the mechanics described below for you. Before You Start ---------------- Before you send patches at all, make sure that each patch makes sense. In particular: - A given patch should not break anything, even if later patches fix the problems that it causes. The source tree should still build and work after each patch is applied. (This enables `git bisect` to work best.) - A patch should make one logical change. Don't make multiple, logically unconnected changes to disparate subsystems in a single patch. - A patch that adds or removes user-visible features should also update the appropriate user documentation or manpages. Consider adding an item to NEWS for nontrivial changes. Check "Feature Deprecation Guidelines" section in this document if you intend to remove user-visible feature. Testing is also important: - Test a patch that modifies existing code with ``make check`` before submission. Refer to the "Unit Tests" in :doc:`/topics/testing`, for more information. We also encourage running the kernel and userspace system tests. - Consider testing a patch that adds or deletes files with ``make distcheck`` before submission. - A patch that modifies Linux kernel code should be at least build-tested on various Linux kernel versions before submission. I suggest versions 3.10 and whatever the current latest release version is at the time. - A patch that adds a new feature should add appropriate tests for the feature. A bug fix patch should preferably add a test that would fail if the bug recurs. If you are using GitHub, then you may utilize the GitHub Actions CI system. This will run the above tests automatically when you push changes to your repository. Email Subject ------------- The subject line of your email should be in the following format: [PATCH ovn /] : Where: ``[PATCH ovn]``: indicates that this is the patch and it is targeted for OVN project. This is important since OVN and OVS are using same mailing lists for development. ``ovn`` word could be added manually or by using ``git format-patch --subject-prefix="PATCH ovn" ...``. It might be useful to add following configuration to a local ``.git/config``:: [format] subjectPrefix = "PATCH ovn" ``/``: indicates that this is the nth of a series of m patches. It helps reviewers to read patches in the correct order. You may omit this prefix if you are sending only one patch. ````: indicates the area of OVN to which the change applies (often the name of a source file or a directory). You may omit it if the change crosses multiple distinct pieces of code. ````: briefly describes the change. Use the imperative form, e.g. "Force SNAT for multiple gateway routers." or "Fix daemon exit for bad datapaths or flows." Try to keep the summary short, about 50 characters wide. The subject, minus the ``[PATCH ovn /]`` prefix, becomes the first line of the commit's change log message. Description ----------- The body of the email should start with a more thorough description of the change. This becomes the body of the commit message, following the subject. There is no need to duplicate the summary given in the subject. Please limit lines in the description to 75 characters in width. That allows the description to format properly even when indented (e.g. by "git log" or in email quotations). The description should include: - The rationale for the change. - Design description and rationale (but this might be better added as code comments). - Testing that you performed (or testing that should be done but you could not for whatever reason). - Tags (see below). There is no need to describe what the patch actually changed, if the reader can see it for himself. If the patch refers to a commit already in the OVN repository, please include both the commit number and the subject of the patch, e.g. 'commit 632d136c (vswitch: Remove restriction on datapath names.)'. If you, the person sending the patch, did not write the patch yourself, then the very first line of the body should take the form ``From: ``, followed by a blank line. This will automatically cause the named author to be credited with authorship in the repository. Tags ---- The description ends with a series of tags, written one to a line as the last paragraph of the email. Each tag indicates some property of the patch in an easily machine-parseable manner. Please don't wrap a tag across multiple lines. If necessary, it's OK to have a tag extend beyond the customary maximum width of a commit message. Examples of common tags follow. ``Signed-off-by: Author Name `` Informally, this indicates that Author Name is the author or submitter of a patch and has the authority to submit it under the terms of the license. The formal meaning is to agree to the Developer's Certificate of Origin (see below). If the author and submitter are different, each must sign off. If the patch has more than one author, all must sign off. Signed-off-by tags should be the last tags in the commit message. If the author (or authors) and submitter are different, the author tags should come first. More generally, occasionally a patch might pass through a chain of submitters, and in such a case the sign-offs should be arranged in chronological order. :: Signed-off-by: Author Name Signed-off-by: Submitter Name ``Co-authored-by: Author Name `` Git can only record a single person as the author of a given patch. In the rare event that a patch has multiple authors, one must be given the credit in Git and the others must be credited via Co-authored-by: tags. (All co-authors must also sign off.) ``Acked-by: Reviewer Name `` Reviewers will often give an ``Acked-by:`` tag to code of which they approve. It is polite for the submitter to add the tag before posting the next version of the patch or applying the patch to the repository. Quality reviewing is hard work, so this gives a small amount of credit to the reviewer. Not all reviewers give ``Acked-by:`` tags when they provide positive reviews. It's customary only to add tags from reviewers who actually provide them explicitly. ``Tested-by: Tester Name `` When someone tests a patch, it is customary to add a Tested-by: tag indicating that. It's rare for a tester to actually provide the tag; usually the patch submitter makes the tag himself in response to an email indicating successful testing results. ``Tested-at: `` When a test report is publicly available, this provides a way to reference it. Typical s would be build logs from autobuilders or references to mailing list archives. Some autobuilders only retain their logs for a limited amount of time. It is less useful to cite these because they may be dead links for a developer reading the commit message months or years later. ``Reported-by: Reporter Name `` When a patch fixes a bug reported by some person, please credit the reporter in the commit log in this fashion. Please also add the reporter's name and email address to the list of people who provided helpful bug reports in the AUTHORS file at the top of the source tree. Fairly often, the reporter of a bug also tests the fix. Occasionally one sees a combined "Reported-and-tested-by:" tag used to indicate this. It is also acceptable, and more common, to include both tags separately. (If a bug report is received privately, it might not always be appropriate to publicly credit the reporter. If in doubt, please ask the reporter.) ``Requested-by: Requester Name `` When a patch implements a request or a suggestion made by some person, please credit that person in the commit log in this fashion. For a helpful suggestion, please also add the person's name and email address to the list of people who provided suggestions in the AUTHORS file at the top of the source tree. (If a suggestion or a request is received privately, it might not always be appropriate to publicly give credit. If in doubt, please ask.) ``Suggested-by: Suggester Name `` See ``Requested-by:``. ``CC: Person `` This is a way to tag a patch for the attention of a person when no more specific tag is appropriate. One use is to request a review from a particular person. It doesn't make sense to include the same person in CC and another tag, so e.g. if someone who is CCed later provides an Acked-by, add the Acked-by and remove the CC at the same time. ``Reported-at: `` If a patch fixes or is otherwise related to a bug reported in a public bug tracker, please include a reference to the bug in the form of a URL to the specific bug, e.g.: :: Reported-at: https://bugs.debian.org/743635 This is also an appropriate way to refer to bug report emails in public email archives, e.g.: :: Reported-at: https://mail.openvswitch.org/pipermail/ovs-dev/2014-June/284495.html ``Submitted-at: `` If a patch was submitted somewhere other than the OVN development mailing list, such as a GitHub pull request, this header can be used to reference the source. :: Submitted-at: https://github.com/ovn-org/ovn/pull/138 ``VMware-BZ: #1234567`` If a patch fixes or is otherwise related to a bug reported in a private bug tracker, you may include some tracking ID for the bug for your own reference. Please include some identifier to make the origin clear, e.g. "VMware-BZ" refers to VMware's internal Bugzilla instance and "ONF-JIRA" refers to the Open Networking Foundation's JIRA bug tracker. ``ONF-JIRA: EXT-12345`` See ``VMware-BZ:``. ``Bug #1234567.`` These are obsolete forms of VMware-BZ: that can still be seen in old change log entries. (They are obsolete because they do not tell the reader what bug tracker is referred to.) ``Issue: 1234567`` See ``Bug:``. ``Fixes: 63bc9fb1c69f (“packets: Reorder CS_* flags to remove gap.â€)`` If you would like to record which commit introduced a bug being fixed, you may do that with a “Fixes†header. This assists in determining which OVN releases have the bug, so the patch can be applied to all affected versions. The easiest way to generate the header in the proper format is with this git command. This command also CCs the author of the commit being fixed, which makes sense unless the author also made the fix or is already named in another tag: :: $ git log -1 --pretty=format:"CC: %an <%ae>%nFixes: %h (\"%s\")" \ --abbrev=12 COMMIT_REF ``Vulnerability: CVE-2016-2074`` Specifies that the patch fixes or is otherwise related to a security vulnerability with the given CVE identifier. Other identifiers in public vulnerability databases are also suitable. If the vulnerability was reported publicly, then it is also appropriate to cite the URL to the report in a Reported-at tag. Use a Reported-by tag to acknowledge the reporters. Developer's Certificate of Origin --------------------------------- To help track the author of a patch as well as the submission chain, and be clear that the developer has authority to submit a patch for inclusion in OVN please sign off your work. The sign off certifies the following: :: Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. See also http://developercertificate.org/. Feature Deprecation Guidelines ------------------------------ OVN is intended to be user friendly. This means that under normal circumstances we don't abruptly remove features from OVN that some users might still be using. Otherwise, if we would, then we would possibly break our user setup when they upgrade and would receive bug reports. Typical process to deprecate a feature in OVN is to: (a) Mention deprecation of a feature in the NEWS file. Also, mention expected release or absolute time when this feature would be removed from OVN altogether. Don't use relative time (e.g. "in 6 months") because that is not clearly interpretable. (b) If OVN is configured to use deprecated feature it should print a warning message to the log files clearly indicating that feature is deprecated and that use of it should be avoided. (c) If this feature is mentioned in man pages, then add "Deprecated" keyword to it. Also, if there is alternative feature to the one that is about to be marked as deprecated, then mention it in (a), (b) and (c) as well. Remember to follow-up and actually remove the feature from OVN codebase once deprecation grace period has expired and users had opportunity to use at least one OVN release that would have informed them about feature deprecation! OVN upgrades ------------ If the patch introduces any new OVN actions or updates existing OVN actions, then make sure to check the function ovn_get_internal_version() in lib/ovn-util.c and increment the macro - OVN_INTERNAL_MINOR_VER. Adding new OVN actions or changing existing OVN actions can have datapath disruptions during OVN upgrades. To minimize disruptions, OVN supports version matching between ovn-northd and ovn-controller and it is important to update the internal OVN version when the patch introduces such changes. Comments -------- If you want to include any comments in your email that should not be part of the commit's change log message, put them after the description, separated by a line that contains just ``---``. It may be helpful to include a diffstat here for changes that touch multiple files. Patch ----- The patch should be in the body of the email following the description, separated by a blank line. Patches should be in ``diff -up`` format. We recommend that you use Git to produce your patches, in which case you should use the ``-M -C`` options to ``git diff`` (or other Git tools) if your patch renames or copies files. `Quilt `__ might be useful if you do not want to use Git. Patches should be inline in the email message. Some email clients corrupt white space or wrap lines in patches. There are hints on how to configure many email clients to avoid this problem on `kernel.org `__. If you cannot convince your email client not to mangle patches, then sending the patch as an attachment is a second choice. Follow the style used in the code that you are modifying. :doc:`coding-style` file describes the coding style used in most of OVN. You may use the ``utilities/checkpatch.py`` utility as a quick check for certain commonly occurring mistakes (improper leading/trailing whitespace, missing signoffs, some improper formatted patch files). Example ------- :: From fa29a1c2c17682879e79a21bb0cdd5bbe67fa7c0 Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Thu, 8 Dec 2011 13:17:24 -0800 Subject: [PATCH] datapath: Alphabetize include/net/ipv6.h compat header. Signed-off-by: Jesse Gross --- datapath/linux/Modules.mk | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/datapath/linux/Modules.mk b/datapath/linux/Modules.mk index fdd952e..f6cb88e 100644 --- a/datapath/linux/Modules.mk +++ b/datapath/linux/Modules.mk @@ -56,11 +56,11 @@ openvswitch_headers += \ linux/compat/include/net/dst.h \ linux/compat/include/net/genetlink.h \ linux/compat/include/net/ip.h \ + linux/compat/include/net/ipv6.h \ linux/compat/include/net/net_namespace.h \ linux/compat/include/net/netlink.h \ linux/compat/include/net/protocol.h \ linux/compat/include/net/route.h \ - linux/compat/include/net/ipv6.h \ linux/compat/genetlink.inc both_modules += brcompat -- 1.7.7.3 ovn-25.09.0~git20250813.23884f5/Documentation/internals/documentation.rst000066400000000000000000000053341504532661100253650ustar00rootroot00000000000000.. Copyright (c) 2017 Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============================= How OVN's Documentation Works ============================= This document provides a brief overview on how the documentation build system within OVN works. This is intended to maximize the "bus factor" and share best practices with other projects. reStructuredText and Sphinx --------------------------- Nearly all of OVN's documentation is written in `reStructuredText`__, with man pages being the sole exception. Of this documentation, most of it is fed into `Sphinx`__, which provides not only the ability to convert rST to a variety of other output formats but also allows for things like cross-referencing and indexing. for more information on the two, refer to the :doc:`contributing/documentation-style`. sphinx_rtd_theme ---------------- The documentation uses `sphinx_rtd_theme`, which can be found on GitHub__ and is published on pypi__. It is also packaged in major distributions. If building locally and the package is installed, it will be used. If the package is not installed, Sphinx will fallback to the default theme. Read the Docs ------------- The documentation is hosted on readthedocs.org and a CNAME redirect is in place to allow access from docs.ovn.org. *Read the Docs* provides a couple of nifty features for us, such as automatic building of docs whenever there are changes and versioning of documentation. The *Read the Docs* project is currently maintained by Stephen Finucane, Russell Bryant and Ben Pfaff. ovn.org ------- The sources for ovn.org are maintained separately from docs.ovn.org. For modifications to this site, refer to the `GitHub project`__. __ http://docutils.sourceforge.net/rst.html __ http://www.sphinx-doc.org/ __ https://github.com/readthedocs/sphinx_rtd_theme __ https://pypi.python.org/pypi/sphinx_rtd_theme __ https://github.com/ovn-org/ovn-org.github.io ovn-25.09.0~git20250813.23884f5/Documentation/internals/index.rst000066400000000000000000000025161504532661100236220ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============= OVN Internals ============= Information for people who want to know more about the OVN project itself and how they might involved. .. toctree:: :maxdepth: 2 contributing/index mailing-lists patchwork release-process bugs security charter committer-emeritus-status committer-responsibilities committer-grant-revocation authors maintainers documentation ovs_submodule ovn-25.09.0~git20250813.23884f5/Documentation/internals/mailing-lists.rst000066400000000000000000000043651504532661100252730ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============= Mailing Lists ============= .. important:: Report security issues **only** to security@openvswitch.org. For more information, refer to our :doc:`security policies `. ovs-announce ------------ The `ovs-announce`__ mailing list is used to announce new versions of Open vSwitch and OVN and is extremely low-volume. `(subscribe)`__ `(archives)`__ __ ovs-announce@openvswitch.org __ https://mail.openvswitch.org/mailman/listinfo/ovs-announce/ __ https://mail.openvswitch.org/pipermail/ovs-announce/ ovs-discuss ----------- The `ovs-discuss`__ mailing list is used to discuss plans and design decisions for Open vSwitch and OVN. It is also an appropriate place for user questions. `(subscribe)`__ `(archives)`__ __ ovs-discuss@openvswitch.org __ https://mail.openvswitch.org/mailman/listinfo/ovs-discuss/ __ https://mail.openvswitch.org/pipermail/ovs-discuss/ ovs-dev ------- The `ovs-dev`__ mailing list is used to discuss development and review code before being committed. `(subscribe)`__ `(archives)`__ __ ovs-dev@openvswitch.org __ https://mail.openvswitch.org/mailman/listinfo/ovs-dev/ __ https://mail.openvswitch.org/pipermail/ovs-dev/ bugs ----- The `bugs`__ mailing list is an alias for the discuss mailing list. __ bugs@openvswitch.org security -------- The `security`__ mailing list is for submitting security vulnerabilities to the security team. __ security@openvswitch.org ovn-25.09.0~git20250813.23884f5/Documentation/internals/maintainers.rst000066400000000000000000000022241504532661100250210ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. .. include:: ../../MAINTAINERS.rst :end-before: Cut here for the Documentation/internals/maintainers.rst .. |responsibilities| replace:: :doc:`committer-responsibilities` .. |grant-revocation| replace:: :doc:`committer-grant-revocation` .. |emeritus-status| replace:: :doc:`committer-emeritus-status` ovn-25.09.0~git20250813.23884f5/Documentation/internals/ovs_submodule.rst000066400000000000000000000115751504532661100254060ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============= OVS Submodule ============= Prior to 2020, OVN did not exist as its own repo. Instead, OVN was a subdirectory within OVS. OVN grew up being closely intertwined with OVS. Compiling OVS would also compile OVN. OVN used OVS libraries directly, and there was no concern about trying to maintain any level of compatibility between OVS and OVN since they were the same codebase. In 2020, OVN was split off from OVS. This meant that it became necessary to consider compatibility between OVS and OVN. At compile time, we use a submodule to ensure that OVS libraries that OVN relies on will behave as expected. Runtime compatibility is a separate topic outside the scope of this document. Developing with the OVS submodule --------------------------------- Most OVN development will happen independently of the OVS submodule. However, there may be times that in order to make a change in OVN, an accompanying change is required in OVS as well. For instance, it may be that a change to OVSDB's client API is required for OVN to fix a bug. In this situation, make the necessary OVS change first and submit this fix to OVS based on their current code submission guidelines. Once the change has been accepted by OVS, then you can submit an OVN patch that includes changing the submodule to point at the OVS commit where your change was accepted. Submodules for releases ----------------------- For OVN releases, it is preferred for the OVS submodule to point to a stable release of OVS. Therefore, as part of the release process for OVN, we will point the submodule to the latest stable version of OVS before releasing. The exception to this is if the current OVS submodule is pointing to a commit that is not in a current stable release of OVS. In that case, the submodule will continue to point to that particular commit. We may, however, bump the submodule to the next stable version of OVS at a later time. As an example, let's assume that the OVS commit history looks something like this in the main branch: :: (Newest) Commit 4 | | Commit 2 ------------------------------- Commit 3 (used to create OVS branch-Y) (latest stable release on OVS branch-Y) | | Commit 1 (Oldest) Let's say that we are planning to release OVN version X. At this point, the submodule is pointing to Commit 1. As part of the release process, we will bump the OVS submodule in OVN to point to Commit 2, or more likely the latest OVS release on branch-y (Commit 3). This way, the released version of OVN is based on a stable release of OVS, and it has all of the necessary changes that we require. What if the OVS submodule currently points to Commit 4, though? There is no stable OVS release that exists after this commit. In this case, we have two choices: # Create OVN release X and point the OVS submodule to Commit 4. At a later time, if it makes sense to do so, we may bump the submodule to the new OVS stable release on branch-Z when it is released, since Commit 4 will be included in that branch. # If Commit 4 is a bug fix in OVS, then we can try to ensure that Commit 4 gets backported to OVS branch-Y, and then point the submodule commit to the next stable release of OVS on branch-Y. For choice 1, the decision of whether to update the submodule commit to OVS branch-Z is based on several factors. - Is OVN release X still being supported? - Is there any known benefit to updating the submodule? E.g., are there performance improvements we could take advantage of by updating the submodule? - Is there risk in updating the submodule? For choice 2, it's preferable to bump to a new stable OVS release but if the bug fix is urgent maintainers may decide to temporarily point the OVS submodule bump to the tip of brach-Y. For an LTS of OVN, we might update the submodule several times during its lifetime as more new OVS branches are released. For a standard release, it is less likely that we will update the OVS submodule during the standard release's lifetime. ovn-25.09.0~git20250813.23884f5/Documentation/internals/patchwork.rst000066400000000000000000000054141504532661100245150ustar00rootroot00000000000000.. Copyright (C) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========= Patchwork ========= OVN uses `Patchwork`__ to track the status of patches sent to the :doc:`ovs-dev mailing list `. Our Patchwork instance can be found on `ozlabs.org`__. Patchwork provides a number of useful features for developers working on OVN: - Tracking the lifecycle of patches (accepted, rejected, under-review, ...) - Assigning reviewers (delegates) to patches - Downloading/applying patches, series, and bundles via the web UI or the REST API (see :ref:`git-pw`) - A usable UI for viewing patch discussions __ https://github.com/getpatchwork/patchwork __ https://patchwork.ozlabs.org/project/ovn/list/ .. _git-pw: git-pw ------ The *git-pw* tool provides a way to download and apply patches, series, and bundles. You can install *git-pw* from `PyPi`__ like so:: $ pip install --user git-pw To actually use *git-pw*, you must configure it with the Patchwork instance URL, Patchwork project, and your Patchwork user authentication token. The URL and project are provided below, but you must obtain your authentication token from your `Patchwork User Profile`__ page. If you do not already have a Patchwork user account, you should create one now. Once your token is obtained, configure *git-pw* as below. Note that this must be run from within the OVN Git repository:: $ git config pw.server https://patchwork.ozlabs.org/ $ git config pw.project ovn $ git config pw.token $PW_TOKEN # using the token obtained earlier Once configured, run the following to get information about available commands:: $ git pw --help __ https://pypi.python.org/pypi/git-pw __ https://patchwork.ozlabs.org/user/ .. _pwclient: pwclient -------- The *pwclient* is a legacy tool that provides some of the functionality of *git-pw* but uses the legacy XML-RPC API. It is considered deprecated in its current form and *git-pw* should be used instead. ovn-25.09.0~git20250813.23884f5/Documentation/internals/release-process.rst000066400000000000000000000224611504532661100256100ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================== OVN Release Process =================== This document describes the process ordinarily used for OVN development and release. Exceptions are sometimes necessary, so all of the statements here should be taken as subject to change through rough consensus of OVN contributors, obtained through public discussion on, e.g., ovs-dev or the #openvswitch IRC channel. Release Strategy ---------------- OVN feature development takes place on the "main" branch. Ordinarily, new features are rebased against main and applied directly. For features that take significant development, sometimes it is more appropriate to merge a separate branch into main; please discuss this on ovs-dev in advance. The process of making a release has the following stages. See `Release Scheduling`_ for the timing of each stage: 1. "Soft freeze" of the main branch. During the freeze, we ask committers to refrain from applying patches that add new features unless those patches were already posted for public review before the freeze began. Bug fixes are welcome at any time. Please propose and discuss exceptions on ovs-dev. 2. Fork a release branch from main, named for the expected release number, e.g. "branch-25.09" for the branch that will yield OVN 25.09.x. Release branches are intended for testing and stabilization. At this stage and in later stages, they should receive only bug fixes, not new features. Bug fixes applied to release branches should be backports of corresponding bug fixes to the main branch, except for bugs present only on release branches (which are rare in practice). At this stage, sometimes there can be exceptions to the rule that a release branch receives only bug fixes. Like bug fixes, new features on release branches should be backports of the corresponding commits on the main branch. Features to be added to release branches should be limited in scope and risk and discussed on ovs-dev before creating the branch. In order to keep the CI stable on the new release branch, the Ubuntu container should be pinned to the current LTS version in the Dockerfile e.g. registry.hub.docker.com/library/ubuntu:22.04. 3. When committers come to rough consensus that the release is ready, they release the .0 release on its branch, e.g. 25.09.0 for branch-25.09. To make the actual release, a committer pushes a signed tag named, e.g. v25.09.0, to the OVN repository, makes a release tarball available on openvswitch.org, and posts a release announcement to ovs-announce. 4. As bug fixes accumulate, or after important bugs or vulnerabilities are fixed, committers may make additional releases from a branch: 25.09.1, 25.09.2, and so on. The process is the same for these additional release as for a .0 release. .. _long-term-support: Long-term Support Branches -------------------------- The OVN project will periodically designate a release branch as "long-term support" or LTS for short. An LTS branch has the distinction of being maintained for longer than a standard branch. LTS branches will receive bug fixes and have releases made regularly until the point that another LTS is released. At that point, the old LTS will receive an additional year of critical and security fixes. Critical fixes are those that are required to ensure basic operation (e.g. memory leak fixes, crash fixes). Security fixes are those that address concerns about exploitable flaws in OVN and that have a corresponding CVE report. Whenever such a fix is applied, a new release will be made for the LTS version. LTS branches are scheduled to be created once every two years. This means that any given LTS will receive bug fix support for two years, followed by one year of critical bug fixes and security fixes. The current LTS version is documented on the `Long Term Support Releases`__ page of `ovn.org`__. Standard-term Support Versions ------------------------------ Versions of OVN that are not designated as LTS versions are standard-term support releases. Standard term support versions will have releases made regularly for one year. There are no additional windows for which releases will be made for critical or security fixes. The branches for standard term support versions may receive bug fixes and critical and security fixes after the OVN team has stopped creating regular releases. This is to facilitate easy backporting of fixes to LTS versions that are still receiving regular releases. Even though the branch may receive additional fixes, no releases will be made with these fixes. Sometimes, a fix can be backported to these branches if requested by the user or author of that fix. The request maybe rejected by the maintainers if it is deemed risky or complex. Release Numbering ----------------- The version number on main should normally end in .90. This indicates that the OVN version is "almost" the next version to branch. Forking main into branch-x.y requires two commits to main. The first is titled "Prepare for x.y.0" and increments the version number to x.y. This is the initial commit on branch-x.y. The second is titled "Prepare for post-x.y.0 (x.y.90)" and increments the version number to x.y.90. The version number on a release branch is x.y.z, where x is the current year, y is the month of the release, and z is initially 0. Making a release requires two commits. The first is titled *Set release dates for x.y.z.* and updates NEWS and debian/changelog to specify the release date of the new release. This commit is the one made into a tarball and tagged. The second is titled *Prepare for x.y.(z+1).* and increments the version number and adds a blank item to NEWS with an unspecified date. Release Scheduling ------------------ OVN makes releases at the following six-month cadence. All dates are approximate: +---------------+---------------------+--------------------------------------+ | Time (months) | Example Dates | Stage | +---------------+---------------------+--------------------------------------+ | T | Mar 1, Sep 1, ... | Begin x.y release cycle | +---------------+---------------------+--------------------------------------+ | T + 4.5 | Jul 15, Jan 15, ... | "Soft freeze" main for x.y release | +---------------+---------------------+--------------------------------------+ | T + 5 | Aug 1, Feb 1, ... | Fork branch-x.y from main | +---------------+---------------------+--------------------------------------+ | T + 6 | Sep 1, Mar 1, ... | Release version x.y.0 | +---------------+---------------------+--------------------------------------+ Subsequent Releases ~~~~~~~~~~~~~~~~~~~ Beyond the .0 release of an OVN version, we will schedule further regular releases from its development branch. The most recent release branch, as well as the current LTS branch, will receive new releases every two months. If the most recent release branch is an LTS branch, then that branch alone will have releases made every two months. Other standard-term support branches that are still under support will receive new releases every three months. If for some reason, no changes occur to a supported OVN branch during a release period, then no release will be made on that branch for that period. Therefore, there is no guarantee about the exact number of releases to be expected for any given OVN version. Release Calendar ---------------- The 2025 timetable is shown below. Note that these dates are not set in stone. If extenuating circumstances arise, a release may be delayed from its target date. +---------+-------------+-----------------+---------+ | Release | Soft Freeze | Branch Creation | Release | +---------+-------------+-----------------+---------+ | 25.03.0 | Jan 24 | Feb 7 | Mar 7 | +---------+-------------+-----------------+---------+ | 25.09.0 | Jul 25 | Aug 8 | Sep 5 | +---------+-------------+-----------------+---------+ Below is the 2026 timetable +---------+-------------+-----------------+---------+ | Release | Soft Freeze | Branch Creation | Release | +---------+-------------+-----------------+---------+ | 26.03.0 | Jan 23 | Feb 6 | Mar 6 | +---------+-------------+-----------------+---------+ | 26.09.0 | Jul 24 | Aug 7 | Sep 4 | +---------+-------------+-----------------+---------+ Contact ------- Use dev@openvswitch.org to discuss the OVN development and release process. __ https://www.ovn.org/en/releases/#long-term-support __ https://www.ovn.org ovn-25.09.0~git20250813.23884f5/Documentation/internals/security.rst000066400000000000000000000255461504532661100243720ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ====================== OVN's Security Process ====================== This is a proposed security vulnerability reporting and handling process for OVN. It is based on the OpenStack vulnerability management process described at https://wiki.openstack.org/wiki/Vulnerability\_Management. The OVN security team coordinates vulnerability management using the ovs-security mailing list. Membership in the security team and subscription to its mailing list consists of a small number of trustworthy people, as determined by rough consensus of the OVN committers. The OVN security team should include OVN committers, to ensure prompt and accurate vulnerability assessments and patch review. We encourage everyone involved in the security process to GPG-sign their emails. We additionally encourage GPG-encrypting one-on-one conversations as part of the security process. What is a vulnerability? ------------------------ All vulnerabilities are bugs, but not every bug is a vulnerability. Vulnerabilities compromise one or more of: * Confidentiality (personal or corporate confidential data). * Integrity (trustworthiness and correctness). * Availability (uptime and service). Here are some examples of vulnerabilities to which one would expect to apply this process: * A crafted packet that causes a kernel or userspace crash (Availability). * A flow translation bug that misforwards traffic in a way likely to hop over security boundaries (Integrity). * An OpenFlow protocol bug that allows a controller to read arbitrary files from the file system (Confidentiality). * Misuse of the OpenSSL library that allows bypassing certificate checks (Integrity). * A bug (memory corruption, overflow, ...) that allows one to modify the behaviour of OVN through external configuration interfaces such as OVSDB (Integrity). * Privileged information is exposed to unprivileged users (Confidentiality). If in doubt, please do use the vulnerability management process. At worst, the response will be to report the bug through the usual channels. Step 1: Reception ----------------- To report an OVN vulnerability, send an email to the ovs-security mailing list (see contact_ at the end of this document). A security team member should reply to the reporter acknowledging that the report has been received. Consider reporting the information mentioned in :doc:`bugs`, where relevant. Reporters may ask for a GPG key while initiating contact with the security team to deliver more sensitive reports. Step 2: Assessment ------------------ The security team should discuss the vulnerability. The reporter should be included in the discussion (via "CC") to an appropriate degree. The assessment should determine which OVN versions are affected (e.g. every version, only the latest release, only unreleased versions), the privilege required to take advantage of the vulnerability (e.g. any network user, any local L2 network user, any local system user, connected OpenFlow controllers), the severity of the vulnerability, and how the vulnerability may be mitigated (e.g. by disabling a feature). The treatment of the vulnerability could end here if the team determines that it is not a realistic vulnerability. Step 3a: Document ----------------- The security team develops a security advisory document. The security team may, at its discretion, include the reporter (via "CC") in developing the security advisory document, but in any case should accept feedback from the reporter before finalizing the document. When the document is final, the security team should obtain a CVE for the vulnerability from a CNA (https://cve.mitre.org/cve/cna.html). The document credits the reporter and describes the vulnerability, including all of the relevant information from the assessment in step 2. Suitable sections for the document include: :: * Title: The CVE identifier, a short description of the vulnerability. The title should mention OVN. In email, the title becomes the subject. Pre-release advisories are often passed around in encrypted email, which have plaintext subjects, so the title should not be too specific. * Description: A few paragraphs describing the general characteristics of the vulnerability, including the versions of OVN that are vulnerable, the kind of attack that exposes the vulnerability, and potential consequences of the attack. The description should re-state the CVE identifier, in case the subject is lost when an advisory is sent over email. * Mitigation: How an OVN administrator can minimize the potential for exploitation of the vulnerability, before applying a fix. If no mitigation is possible or recommended, explain why, to reduce the chance that at-risk users believe they are not at risk. * Fix: Describe how to fix the vulnerability, perhaps in terms of applying a source patch. The patch or patches themselves, if included in the email, should be at the very end of the advisory to reduce the risk that a reader would stop reading at this point. * Recommendation: A concise description of the security team's recommendation to users. * Acknowledgments: Thank the reporters. * Vulnerability Check: A step-by-step procedure by which a user can determine whether an installed copy of OVN is vulnerable. The procedure should clearly describe how to interpret the results, including expected results in vulnerable and not-vulnerable cases. Thus, procedures that produce clear and easily distinguished results are preferred. The procedure should assume as little understanding of Open vSwitch as possible, to make it more likely that a competent administrator who does not specialize in OVN can perform it successfully. The procedure should have minimal dependencies on tools that are not widely installed. Given a choice, the procedure should be one that takes at least some work to turn into a useful exploit. For example, a procedure based on "ovn-appctl" commands, which require local administrator access, is preferred to one that sends test packets to a machine, which only requires network connectivity. The section should say which operating systems it is designed for. If the procedure is likely to be specific to particular architectures (e.g. x86-64, i386), it should state on which ones it has been tested. This section should state the risks of the procedure. For example, if it can crash OVN or disrupt packet forwarding, say so. It is more useful to explain how to check an installed and running OVN than one built locally from source, but if it is easy to use the procedure from a sandbox environment, it can be helpful to explain how to do so. * Patch: If a patch or patches are available, and it is practical to include them in the email, put them at the end. Format them as described in :doc:`contributing/submitting-patches`, that is, as output by "git format-patch". The patch subjects should include the version for which they are suited, e.g. "[PATCH branch-2.3]" for a patch against OVN 2.3.x. If there are multiple patches for multiple versions of OVN, put them in separate sections with clear titles. Multiple patches for a single version of OVN, that must be stacked on top of each other to fix a single vulnerability, are undesirable because users are less likely to apply all of them correctly and in the correct order. Each patch should include a Vulnerability tag with the CVE identifier, a Reported-by tag or tags to credit the reporters, and a Signed-off-by tag to acknowledge the Developer's Certificate of Origin. It should also include other appropriate tags, such as Acked-by tags obtained during review. `CVE-2016-2074 `__ is an example advisory document. Step 3b: Fix ------------ Steps 3a and 3b may proceed in parallel. The security team develops and obtains (private) reviews for patches that fix the vulnerability. If necessary, the security team pulls in additional developers, who must agree to maintain confidentiality. Step 4: Embargoed Disclosure ---------------------------- The security advisory and patches are sent to downstream stakeholders, with an embargo date and time set from the time sent. Downstream stakeholders are expected not to deploy or disclose patches until the embargo is passed. A disclosure date is negotiated by the security team working with the bug submitter as well as vendors. However, the OVN security team holds the final say when setting a disclosure date. The timeframe for disclosure is from immediate (esp. if it's already publicly known) to a few weeks. As a basic default policy, we expect report date to disclosure date to be 10 to 15 business days. Operating system vendors are obvious downstream stakeholders. It may not be necessary to be too choosy about who to include: any major OVN user who is interested and can be considered trustworthy enough could be included. To become a downstream stakeholder, email the ovs-security mailing list. If the vulnerability is already public, skip this step. Step 5: Public Disclosure ------------------------- When the embargo expires, push the (reviewed) patches to appropriate branches, post the patches to the ovs-dev mailing list (noting that they have already been reviewed and applied), post the security advisory to appropriate mailing lists (ovs-announce, ovs-discuss), and post the security advisory on the OVN webpage. When the patch is applied to LTS (long-term support) branches, a new version should be released. The security advisory should be GPG-signed by a security team member with a key that is in a public web of trust. .. _contact: Contact ======= Report security vulnerabilities to the ovs-security mailing list: security@openvswitch.org Report problems with this document to the ovs-bugs mailing list: bugs@openvswitch.org ovn-25.09.0~git20250813.23884f5/Documentation/intro/000077500000000000000000000000001504532661100211115ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/intro/index.rst000066400000000000000000000020731504532661100227540ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =============== Getting Started =============== How to get started with the Open Virtual Network (OVN). .. toctree:: :maxdepth: 2 install/index ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/000077500000000000000000000000001504532661100225575ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/debian.rst000066400000000000000000000020271504532661100245340ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================= Debian Packaging for OVN ================================= OVN packages needs to be split from OVS. This section will be updated once it is done. ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/distributions.rst000066400000000000000000000032711504532661100262160ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================================== Distributions packaging Open Virtual Network (OVN) ================================================== This document lists various popular distributions packaging OVN. .. note:: The packaged version available with distributions may not be latest OVN release. Debian ------- You can use ``apt-get`` or ``aptitude`` to install the .deb packages and must be superuser. Debian has ``ovn-common``, ``ovn-host``, ``ovn-central`` and ``ovn-vtep`` .deb packages. Fedora ------ Fedora provides ``ovn``, ``ovn-host``, ``ovn-central`` and ``ovn-vtep`` rpm packages. Use ``yum`` or ``dnf`` to install the rpm packages and must be superuser. OpenSuSE -------- OpenSUSE provides ``openvswitch-ovn-common``, ```openvswitch-ovn-host``, ```openvswitch-ovn-central`` and ```openvswitch-ovn-vtep`` rpm packages. ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/documentation.rst000066400000000000000000000060171504532661100261660ustar00rootroot00000000000000.. Copyright (c) 2016 Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================================== Open Virtual Network (OVN) Documentation ======================================== This document describes how to build the OVN documentation for use offline. A continuously updated, online version can be found at `docs.ovn.org `__. .. note:: These instructions provide information on building the documentation locally. For information on writing documentation, refer to :doc:`/internals/contributing/documentation-style` Build Requirements ------------------ As described in the :doc:`/internals/contributing/documentation-style`, the OVN documentation is written in reStructuredText and built with Sphinx. A detailed guide on installing Sphinx in many environments is available on the `Sphinx website`__ but, for most Linux distributions, you can install with your package manager. For example, on Debian/Ubuntu run:: $ sudo apt-get install python-sphinx Similarly, on RHEL/Fedora run:: $ sudo dnf install python-sphinx A ``requirements.txt`` is also provided in the ``/Documentation``, should you wish to install using ``pip``:: $ virtualenv .venv $ source .venv/bin/activate $ pip install -r Documentation/requirements.txt __ http://www.sphinx-doc.org/en/master/usage/installation.html Configuring ----------- It's unlikely that you'll need to customize any aspect of the configuration. However, the ``Documentation/conf.py`` is the go-to place for all configuration. This file is well documented and further information is available on the `Sphinx website`__. Building -------- Once Sphinx installed, the documentation can be built using the provided Makefile targets:: $ make docs-check .. important:: The ``docs-check`` target will fail if there are any syntax errors. However, it won't catch more succint issues such as style or grammar issues. As a result, you should always inspect changes visually to ensure the result is as intended. Once built, documentation is available in the ``/Documentation/_build`` folder. Open the root ``index.html`` to browse the documentation. __ http://www.sphinx-doc.org/en/master/config.html ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/fedora.rst000066400000000000000000000071021504532661100245510ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =========================================== Fedora, RHEL 7.x+ Packaging for OVN =========================================== This document provides instructions for building and installing OVN RPM packages on a Fedora Linux host. Instructions for the installation of OVN Fedora Linux host without using RPM packages can be found in the :doc:`general`. These instructions have been tested with Fedora 29 and 30, and are also applicable for RHEL 7.x and its derivatives, including CentOS 7.x and Scientific Linux 7.x. Build Requirements ------------------ You will need to install all required packages to build the RPMs. Newer distributions use ``dnf`` but if it's not available, then use ``yum`` instructions. The command below will install RPM tools and generic build dependencies. And (optionally) include these packages: libcap-ng libcap-ng-devel. DNF: :: $ dnf install @'Development Tools' rpm-build dnf-plugins-core YUM: :: $ yum install @'Development Tools' rpm-build yum-utils Then it is necessary to install OVN specific build dependencies. The dependencies are listed in the SPEC file, but first it is necessary to replace the VERSION tag to be a valid SPEC. The command below will create a temporary SPEC file:: $ sed -e 's/@VERSION@/0.0.1/' rhel/ovn-fedora.spec.in \ > /tmp/ovn.spec And to install specific dependencies, use the corresponding tool below. For some of the dependencies on RHEL you may need to add two additional repositories to help yum-builddep, e.g.:: $ subscription-manager repos --enable=rhel-7-server-extras-rpms $ subscription-manager repos --enable=rhel-7-server-optional-rpms DNF:: $ dnf builddep /tmp/ovn.spec YUM:: $ yum-builddep /tmp/ovn.spec Once that is completed, remove the file ``/tmp/ovn.spec``. Bootstraping ------------ Refer to :ref:`general-bootstrapping`. Configuring ----------- Refer to :ref:`general-configuring`. Building -------- OVN RPMs ~~~~~~~~~~~~~~~ To build OVN RPMs, first generate openvswitch source tarball in your openvwitch source directory by running :: $make dist And then execute the following in the OVN source directory (in which `./configure` was executed): :: $ make rpm-fedora This will create the RPMs `ovn`, `ovn-central`, `ovn-host`, `ovn-vtep`, `ovn-docker`, ``ovn-debuginfo``, ``ovn-central-debuginfo``, ``ovn-host-debuginfo`` and ```ovn-vtep-debuginfo```. You can also have the above commands automatically run the OVN unit tests. This can take several minutes. :: $ make rpm-fedora RPMBUILD_OPT="--with check" Installing ---------- RPM packages can be installed by using the command ``rpm -i``. Package installation requires superuser privileges. Reporting Bugs -------------- Report problems to bugs@openvswitch.org. ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/general.rst000066400000000000000000000515521504532661100247360ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========================================= OVN on Linux, FreeBSD and NetBSD ========================================= This document describes how to build and install OVN on a generic Linux, FreeBSD, or NetBSD host. For specifics around installation on a specific platform, refer to one of the other installation guides listed in :doc:`index`. Obtaining OVN Sources --------------------- The canonical location for OVN source code is its Git repository, which you can clone into a directory named "ovn" with:: $ git clone https://github.com/ovn-org/ovn.git Cloning the repository leaves the "main" branch initially checked out. This is the right branch for general development. If, on the other hand, if you want to build a particular released version, you can check it out by running a command such as the following from the "ovn" directory:: $ git checkout v20.09.0 The repository also has a branch for each release series. For example, to obtain the latest fixes in the OVN 20.09.x release series, which might include bug fixes that have not yet been in any released version, you can check it out from the "ovn" directory with:: $ git checkout origin/branch-20.09 If you do not want to use Git, you can also obtain tarballs for `OVN release versions `, or download a ZIP file for any snapshot from the `GitHub web interface `. .. _general-build-reqs: Build Requirements ------------------ To compile the userspace programs in the OVN distribution, you will need the following software: - Open vSwitch (https://docs.openvswitch.org/en/latest/intro/install/). Open vSwitch is included as a submodule in the OVN source code. It is kept at the minimum recommended version for OVN to build and operate optimally. See below for instructions about how to use a different OVS source location. .. note:: These OVS sources used as a set of libraries to build OVN binaries, so OVS submodule is only recommended to build OVN and *not recommended* to be used as a source for OVS build. To actually build/run OVS binaries (``ovs-vswitchd``, ``ovsdb-server``) use `released versions of Open vSwitch `_ or packages provided in your distribution. - GNU make - One of the following C compilers: - GCC 4.6 or later. - Clang 3.4 or later. - MSVC 2013. Refer to :doc:`windows` for additional Windows build instructions. - libssl, from OpenSSL, is optional but recommended if you plan to connect the OVN services to the OVN DB ovsdb-servers securely. If libssl is installed, then OVN will automatically build with support for it. - Unbound library, from http://www.unbound.net, is optional but recommended if you want to enable ovn-northd, ovn-controller and other utilities to use DNS names when specifying OVSDB remotes. If unbound library is already installed, then OVN will automatically build with support for it. The environment variable OVS_RESOLV_CONF can be used to specify DNS server configuration file (the default file on Linux is /etc/resolv.conf). If you are working from a Git tree or snapshot (instead of from a distribution tarball), or if you modify the OVN build system or the database schema, you will also need the following software: - Autoconf version 2.63 or later. - Automake version 1.10 or later. - libtool version 2.4 or later. (Older versions might work too.) The OVN manpages will include an E-R diagram, in formats other than plain text, only if you have the following: - dot from graphviz (http://www.graphviz.org/). If you are going to extensively modify OVN, consider installing the following to obtain better warnings: - "sparse" version 0.5.1 or later (https://git.kernel.org/pub/scm/devel/sparse/sparse.git/). - GNU make. - clang, version 3.4 or later - flake8 (for Python code) You may find the ovs-dev script found in ``ovs/utilities/ovs-dev.py`` useful. .. _general-install-reqs: Installation Requirements ------------------------- The machine you build OVN on may not be the one you run it on. To simply install and run OVN you require the following software: - Shared libraries compatible with those used for the build. On Linux you should ensure that ``/dev/urandom`` exists. To support TAP devices, you must also ensure that ``/dev/net/tun`` exists. .. _general-bootstrapping: Bootstrapping ------------- This step is not needed if you have downloaded a released tarball. If you pulled the sources directly from an OVN Git tree or got a Git tree snapshot, then run boot.sh in the top source directory to build the "configure" script:: $ ./boot.sh Before configuring OVN, prepare Open vSwitch sources. The easiest way to do this is to use the included OVS submodule in the OVN source tree:: $ git submodule update --init $ cd ovs $ ./boot.sh $ ./configure $ make $ cd .. It is not required to build with the included OVS submodule; however the OVS submodule is guaranteed to include minimum recommended version of OVS libraries to ensure OVN's build and optimal operation. If you wish to build with OVS source code from a different location on the file system, then be sure to configure and build it before building OVN. .. _general-configuring: Configuring ----------- Then configure the package by running the configure script:: $ ./configure If your OVS source directory is not the included OVS submodule, specify the location of the OVS source code using --with-ovs-source:: $ ./configure --with-ovs-source=/path/to/ovs/source If you have built Open vSwitch in a separate directory from its source code, then you need to provide that path in the option - --with-ovs-build. By default all files are installed under ``/usr/local``. OVN expects to find its database in ``/usr/local/etc/ovn`` by default. If you want to install all files into, e.g., ``/usr`` and ``/var`` instead of ``/usr/local`` and ``/usr/local/var`` and expect to use ``/etc/ovn`` as the default database directory, add options as shown here:: $ ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc .. note:: OVN installed with packages like .rpm (e.g. via ``yum install`` or ``rpm -ivh``) and .deb (e.g. via ``apt-get install`` or ``dpkg -i``) use the above configure options. By default, static libraries are built and linked against. If you want to use shared libraries instead:: $ ./configure --enable-shared To use a specific C compiler for compiling Open vSwitch user programs, also specify it on the configure command line, like so:: $ ./configure CC=gcc-4.2 To use 'clang' compiler:: $ ./configure CC=clang To supply special flags to the C compiler, specify them as ``CFLAGS`` on the configure command line. If you want the default CFLAGS, which include ``-g`` to build debug symbols and ``-O2`` to enable optimizations, you must include them yourself. For example, to build with the default CFLAGS plus ``-mssse3``, you might run configure as follows:: $ ./configure CFLAGS="-g -O2 -mssse3" For efficient hash computation special flags can be passed to leverage built-in intrinsics. For example on X86_64 with SSE4.2 instruction set support, CRC32 intrinsics can be used by passing ``-msse4.2``:: $ ./configure CFLAGS="-g -O2 -msse4.2"` Also builtin popcnt instruction can be used to speedup the counting of the bits set in an integer. For example on X86_64 with POPCNT support, it can be enabled by passing ``-mpopcnt``:: $ ./configure CFLAGS="-g -O2 -mpopcnt"` If you are on a different processor and don't know what flags to choose, it is recommended to use ``-march=native`` settings:: $ ./configure CFLAGS="-g -O2 -march=native" With this, GCC will detect the processor and automatically set appropriate flags for it. This should not be used if you are compiling OVS outside the target machine. .. note:: CFLAGS are not applied when building the Linux kernel module. Custom CFLAGS for the kernel module are supplied using the ``EXTRA_CFLAGS`` variable when running make. For example:: $ make EXTRA_CFLAGS="-Wno-error=date-time" If you are a developer and want to enable Address Sanitizer for debugging purposes, at about a 2x runtime cost, you can add ``-fsanitize=address -fno-omit-frame-pointer -fno-common`` to CFLAGS. For example:: $ ./configure CFLAGS="-g -O2 -fsanitize=address -fno-omit-frame-pointer -fno-common" To build the Linux kernel module, so that you can run the kernel-based switch, pass the location of the kernel build directory on ``--with-linux``. For example, to build for a running instance of Linux:: $ ./configure --with-linux=/lib/modules/$(uname -r)/build .. note:: If ``--with-linux`` requests building for an unsupported version of Linux, then ``configure`` will fail with an error message. Refer to the :doc:`/faq/index` for advice in that case. If you plan to do much OVN development, you might want to add ``--enable-Werror``, which adds the ``-Werror`` option to the compiler command line, turning warnings into errors. That makes it impossible to miss warnings generated by the build. For example:: $ ./configure --enable-Werror If you're building with GCC, then, for improved warnings, install ``sparse`` (see "Prerequisites") and enable it for the build by adding ``--enable-sparse``. Use this with ``--enable-Werror`` to avoid missing both compiler and ``sparse`` warnings, e.g.:: $ ./configure --enable-Werror --enable-sparse To build with gcov code coverage support, add ``--enable-coverage``:: $ ./configure --enable-coverage The configure script accepts a number of other options and honors additional environment variables. For a full list, invoke configure with the ``--help`` option:: $ ./configure --help You can also run configure from a separate build directory. This is helpful if you want to build OVN in more than one way from a single source directory, e.g. to try out both GCC and Clang builds. For example:: $ mkdir _gcc && (cd _gcc && ./configure CC=gcc) $ mkdir _clang && (cd _clang && ./configure CC=clang) Under certain loads the ovsdb-server and other components perform better when using the jemalloc memory allocator, instead of the glibc memory allocator. If you wish to link with jemalloc add it to LIBS:: $ ./configure LIBS=-ljemalloc Example usage:: $ # Clone OVS repo $cd /home/foo/ovs $./boot.sh $mkdir _gcc $cd _gcc && ../configure && cd .. $make -C _gcc $ # Clone OVN repo $cd /home/foo/ovn $./boot.sh $./configure --with-ovs-source=/home/foo/ovs/ --with-ovs-build=/home/foo/ovs/_gcc It is expected to configure both Open vSwitch and OVN with the same prefix. .. _general-building: Building -------- 1. Run GNU make in the build directory, e.g.:: $ make or if GNU make is installed as "gmake":: $ gmake If you used a separate build directory, run make or gmake from that directory, e.g.:: $ make -C _gcc $ make -C _clang .. note:: Some versions of Clang and ccache are not completely compatible. If you see unusual warnings when you use both together, consider disabling ccache. 2. Consider running the testsuite. Refer to :doc:`/topics/testing` for instructions. 3. Run ``make install`` to install the executables and manpages into the running system, by default under ``/usr/local``:: $ sudo make install .. _general-starting: Starting -------- Before starting the OVN, start the Open vSwitch daemons. Refer to the Open vSwitch documentation for more details on how to start OVS. On Unix-alike systems, such as BSDs and Linux, starting the OVN suite of daemons is a simple process. OVN includes a shell script, called ovn-ctl which automates much of the tasks for starting and stopping ovn-northd, ovn-controller and ovsdb-servers. After installation, the daemons can be started by using the ovn-ctl utility. This will take care to setup initial conditions, and start the daemons in the correct order. The ovn-ctl utility is located in '$(pkgdatadir)/scripts', and defaults to '/usr/local/share/ovn/scripts'. ovn-ctl utility requires the 'ovs-lib' helper shell script which is present in '/usr/local/share/openvswitch/scripts'. So invoking ovn-ctl as "./ovn-ctl" will fail. An example after install might be:: $ export PATH=$PATH:/usr/local/share/ovn/scripts $ ovn-ctl start_northd $ ovn-ctl start_controller Starting OVN Central services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ OVN central services includes ovn-northd, Northbound and Southbound ovsdb-server. $ export PATH=$PATH:/usr/local/share/ovn/scripts $ ovn-ctl start_northd Refer to ovn-ctl(8) for more information and the supported options. You may wish to manually start the OVN central daemons. Before starting ovn-northd you need to start OVN Northbound and Southbound ovsdb-servers. Before ovsdb-servers can be started, configure the Northbound and Southbound databases:: $ sudo mkdir -p /usr/local/etc/ovn $ sudo ovsdb-tool create /usr/local/etc/ovn/ovnnb_db.db \ ovn-nb.ovsschema $ sudo ovsdb-tool create /usr/local/etc/ovn/ovnsb_db.db \ ovn-sb.ovsschema Configure ovsdb-servers to use databases created above, to listen on a Unix domain socket and to use the SSL/TLS configuration in the database:: $ sudo mkdir -p /usr/local/var/run/ovn $ sudo ovsdb-server /usr/local/etc/ovn/ovnnb_db.db --remote=punix:/usr/local/var/run/ovn/ovnnb_db.sock \ --remote=db:OVN_Northbound,NB_Global,connections \ --private-key=db:OVN_Northbound,SSL,private_key \ --certificate=db:OVN_Northbound,SSL,certificate \ --bootstrap-ca-cert=db:OVN_Northbound,SSL,ca_cert \ --pidfile=/usr/local/var/run/ovn/ovnnb-server.pid --detach --log-file=/usr/local/var/log/ovn/ovnnb-server.log $ sudo ovsdb-server /usr/local/etc/ovn/ovnsb_db.db --remote=punix:/usr/local/var/run/ovn/ovnsb_db.sock \ --remote=db:OVN_Southbound,SB_Global,connections \ --private-key=db:OVN_Southbound,SSL,private_key \ --certificate=db:OVN_Southbound,SSL,certificate \ --bootstrap-ca-cert=db:OVN_Southbound,SSL,ca_cert \ --pidfile=/usr/local/var/run/ovn/ovnsb-server.pid --detach --log-file=/usr/local/var/log/ovn/ovnsb-server.log .. note:: If you built OVN without SSL/TLS support, then omit ``--private-key``, ``--certificate``, and ``--bootstrap-ca-cert``.) Initialize the databases using ovn-nbctl and ovn-sbctl. This is only necessary the first time after you create the databases with ovsdb-tool, though running it at any time is harmless:: $ ovn-nbctl --no-wait init $ ovn-sbctl init Start ``ovn-northd``, telling it to connect to the OVN db servers same Unix domain socket:: $ ovn-northd --pidfile --detach --log-file Starting OVN Central services in containers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For OVN central node, we dont need to load ovs kernel modules on host. Hence, OVN central containers OS need not depend on host OS. Also we can leverage deploying entire OVN control plane in a pod spec for use cases like OVN-kubernetes Export following variables in .env and place it under project root:: $ OVN_BRANCH= $ OVN_VERSION= $ DISTRO= $ KERNEL_VERSION= $ GITHUB_SRC= $ DOCKER_REPO= To build ovn modules:: $ cd utilities/docker $ make build Compiled Modules will be tagged with docker image To Push ovn modules:: $ make push OVN docker image will be pushed to specified docker repo. Start OVN containers using below command:: $ docker run -itd --net=host --name=ovn-nb \ : ovn-nb-tcp $ docker run -itd --net=host --name=ovn-sb \ : ovn-sb-tcp $ docker run -itd --net=host --name=ovn-northd \ : ovn-northd-tcp Start OVN containers in cluster mode for a 3 node cluster using below command on node1:: $ docker run -e "host_ip=" -e "nb_db_port=" -itd \ --name=ovn-nb-raft --net=host --privileged : \ ovn-nb-cluster-create $ docker run -e "host_ip=" -e "sb_db_port=" -itd \ --name=ovn-sb-raft --net=host --privileged : \ ovn-sb-cluster-create $ docker run -e "OVN_NB_DB=tcp::6641,tcp::6641,\ tcp::6641" -e "OVN_SB_DB=tcp::6642,tcp::6642,\ tcp::6642" -itd --name=ovn-northd-raft : \ ovn-northd-cluster Start OVN containers in cluster mode using below command on node2 and node3 \ to make them join the peer using below command:: $ docker run -e "host_ip=" -e "remote_host=" \ -e "nb_db_port=" -itd --name=ovn-nb-raft --net=host \ --privileged : ovn-nb-cluster-join $ docker run -e "host_ip=" -e "remote_host=" \ -e "sb_db_port=" -itd --name=ovn-sb-raft --net=host \ --privileged : ovn-sb-cluster-join $ docker run -e "OVN_NB_DB=tcp::6641,tcp::6641,\ tcp::6641" -e "OVN_SB_DB=tcp::6642,tcp::6642,\ tcp::6642" -itd --name=ovn-northd-raft : \ ovn-northd-cluster Start OVN containers using unix socket:: $ docker run -itd --net=host --name=ovn-nb \ -v /var/run/ovn/:/var/run/ovn/ \ : ovn-nb $ docker run -itd --net=host --name=ovn-sb \ -v /var/run/ovn/:/var/run/ovn/ : ovn-sb $ docker run -itd --net=host --name=ovn-northd \ -v /var/run/ovn/:/var/run/ovn/ : ovn-northd .. note:: Current ovn central components comes up in docker image in a standalone and cluster mode with protocol tcp. The debian docker file use ubuntu 16.04 as a base image for reference. User can use any other base image for debian, e.g. u14.04, etc. RHEL based docker support is now added with centos7 as a base image. Starting OVN host service ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On each chassis, ovn-controller service should be started. ovn-controller assumes it gets configuration information from the Open_vSwitch table of the local OVS instance. Refer to the ovn-controller(8) for the configuration keys. Below are the required keys to be configured on each chassis. 1. external_ids:system-id 2. external_ids:ovn-remote 3. external_ids:ovn-encap-type 4. external_ids:ovn-encap-ip You may wish to manually start the ovn-controller service on each chassis. Start the ovn-controller, telling it to connect to the local ovsdb-server Unix domain socket:: $ ovn-controller --pidfile --detach --log-file Starting OVN host service in containers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For OVN host too, we dont need to load ovs kernel modules on host. Hence, OVN host container OS need not depend on host OS. Also we can leverage deploying OVN host in a pod spec for use cases like OVN-kubernetes to manage OVS which can be running as a service on host or in container. Start ovsdb-server and ovs-vswitchd components as per http://docs.openvswitch.org/en/latest/intro/install/general/ start local ovn-controller with below command if ovs is also running in container:: $ docker run -itd --net=host --name=ovn-controller \ --volumes-from=ovsdb-server \ : ovn-controller start local ovn-controller with below command if ovs is running as a service:: $ docker run -itd --net=host --name=ovn-controller \ -v /var/run/openvswitch/:/var/run/openvswitch/ \ : ovn-controller Validating ---------- At this point you can use ovn-nbctl on the central node to set up logical switches and ports and other OVN logical entities. For example, to create a logical switch ``sw0`` and add logical port ``sw0-p1`` :: $ ovn-nbctl ls-add sw0 $ ovn-nbctl lsp-add sw0 sw0-p1 $ ovn-nbctl show Refer to ovn-nbctl(8) and ovn-sbctl (8) for more details. When using ovn in container, exec to container to run above commands:: $ docker exec -it /bin/bash Reporting Bugs -------------- Report problems to bugs@openvswitch.org. ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/index.rst000066400000000000000000000034201504532661100244170ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ===================================== Installing Open Virtual Network (OVN) ===================================== A collection of guides detailing how to install OVN in a variety of different environments and using different configurations. Installation from Source ------------------------ .. TODO(stephenfin): Based on the title alone, the NetBSD doc should probably be merged into the general install doc .. toctree:: :maxdepth: 2 general windows Installation from Packages -------------------------- OVN is packaged on a variety of distributions. The tooling required to build these packages is included in the OVN tree. The instructions are provided below. .. toctree:: :maxdepth: 2 distributions debian fedora Upgrades -------- .. toctree:: :maxdepth: 2 ovn-upgrades Others ------ .. toctree:: :maxdepth: 2 documentation ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/ovn-upgrades.rst000066400000000000000000000230731504532661100257300ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============ OVN Upgrades ============ Since OVN is a distributed system, special consideration must be given to the process used to upgrade OVN across a deployment. This document discusses the two recommended `Upgrade procedures`_, `Rolling upgrade`_ and `Fail-safe upgrade`_. Which one to choose depends on whether you are running a version of OVN that is within range of upstream support for upgrades to the version of OVN you want to upgrade to. Release Notes ------------- You should always check the OVS and OVN release notes (NEWS file) for any release specific notes on upgrades. Open vSwitch ------------ OVN compiles with a particular version of Open vSwitch. This is a build-time dependency. In runtime, OVN should be able to work with any reasonably fresh version of Open vSwitch (not necessarily the version that it was compiled against.) OVN may make use of new runtime features of Open vSwitch that are only available in a particular release. OVN is expected to test for an Open vSwitch feature presence before using it, and gracefully handle scenarios where Open vSwitch doesn't support a particular optional feature, yet. Upgrade procedures ------------------ Rolling upgrade ~~~~~~~~~~~~~~~ 1. `Upgrade ovn-controller`_ 2. `Upgrade OVN Databases and ovn-northd`_ 3. `Upgrade OVN Integration`_ In order to successfully perform a rolling upgrade, the ovn-controller process needs to understand the structure of the database for the version you are upgrading from and to simultaneously. To avoid buildup of complexity and technical debt we limit the span of versions supported for a rolling upgrade on :ref:`long-term-support` (LTS), and it should always be possible to upgrade from the previous LTS version to the next. The following rolling upgrade paths are supported: 1. LTS to the very next LTS release, or to any non-LTS in between the two. 2. Any non-LTS to the very next LTS release. The first LTS version of OVN was 22.03. If you want to upgrade between other versions, you can use the `Fail-safe upgrade`_ procedure. Fail-safe upgrade ~~~~~~~~~~~~~~~~~ 1. Upgrade to the most recent point release or package version available for the major version of OVN you are upgrading from. 2. Enable the version pinning feature in the ovn-controller by setting the ``external_ids:ovn-match-northd-version`` flag to 'true' as documented in the `ovn-controller man page`_. 3. If the version of OVN you are upgrading from does not have the `version pinning check in the incremental processing engine`_, you must stop ovn-northd and manually change the northd_internal_version to ensure the controllers go into fail-safe mode before processing changes induced by the upgrade. $ sudo /usr/share/ovn/scripts/ovn-ctl stop_northd --ovn-manage-ovsdb=no $ sudo ovn-sbctl set sb-global . options:northd_internal_version="foo" 4. `Upgrade OVN Databases and ovn-northd`_ 5. `Upgrade ovn-controller`_ 6. `Upgrade OVN Integration`_ When upgrading between a span of versions that is not supported, you may be at risk for the new ovn-controller process not understanding the structure of the old database, which may lead to data plane downtime for running instances. To avoid this there is a fail safe approach, which involves making the ovn-controller process refrain from making changes to the local flow state when a version mismatch between the ovn-controller and ovn-northd is detected. Steps ----- This section documents individual steps in a upgrade procedure in no particular order. For information on ordering of the steps, please refer to the `Upgrade procedures`_ section. Upgrade ovn-controller ~~~~~~~~~~~~~~~~~~~~~~ You should start by upgrading ovn-controller on each host it's running on. First, you upgrade the OVS and OVN packages. Then, restart the ovn-controller service. You can restart with ovn-ctl:: $ sudo /usr/share/ovn/scripts/ovn-ctl restart_controller or with systemd:: $ sudo systemd restart ovn-controller Upgrade OVN Databases and ovn-northd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The OVN databases and ovn-northd should be upgraded next. Since ovn-controller has already been upgraded, it will be ready to operate on any new functionality specified by the database or logical flows created by ovn-northd. Upgrading the OVN packages installs everything needed for an upgrade. The only step required after upgrading the packages is to restart ovn-northd, which automatically restarts the databases and upgrades the database schema, as well. You may perform this restart using the ovn-ctl script:: $ sudo /usr/share/ovn/scripts/ovn-ctl restart_northd or if you're using a Linux distribution with systemd:: $ sudo systemctl restart ovn-northd In case your deployment utilizes OVN Interconnection (OVN IC) functionality, it is also needed to restart ovn-ic daemons and separately restart ovn-ic databases. You may perform this restart using the ovn-ctl script:: $ sudo /usr/share/openvswitch/scripts/ovn-ctl restart_ic $ sudo /usr/share/openvswitch/scripts/ovn-ctl restart_ic_ovsdb or if you're using a Linux distribution with systemd:: $ sudo systemctl restart ovn-ic $ sudo systemctl restart ovn-ic-db Schema Change +++++++++++++ During database upgrading, if there is schema change, the DB file will be converted to the new schema automatically, if the schema change is backward compatible. OVN tries the best to keep the DB schemas backward compatible. However, there can be situations that an incompatible change is reasonble. An example of such case is to add constraints in the table to ensure correctness. If there were already data that violates the new constraints got added somehow, it will result in DB upgrade failures. In this case, user should manually correct data using ovn-nbctl (for north-bound DB) or ovn-sbctl (for south- bound DB), and then upgrade again following previous steps. Below is a list of known impactible schema changes and how to fix when error encountered. #. Release 2.11: index [type, ip] added for Encap table of south-bound DB to prevent duplicated IPs being used for same tunnel type. If there are duplicated data added already (e.g. due to improper chassis management), a convenient way to fix is to find the chassis that is using the IP with command:: $ ovn-sbctl show Then delete the chassis with command:: $ ovn-sbctl chassis-del #. Release 22.12: index [transit_switch, availability_zone, route_table, ip_prefix, nexthop] added for OVN Interconnection Southbound DB table Route. If there are duplicated records in this table, users are adviced to upgrade ovn-ic daemons in all availability zones first and after that convert OVS schema (restart ovn-ic database daemon). #. Release 2.11 and earlier: The availability_zone name is added to the external_ids in NB_Global. Therefore, when upgrading to latest versions, update the name column in NB_Global for each availability zone before starting the ovn-ic daemons. The Northbound database upgrade does not handle populating the name column part of schema upgrade. Failing to do this could result in data plane impact, such as remote AZs being unable to update port bindings during gateway chassis failover, new gateway chassis CRUD, etc. Run below command to set the name column in NB_Global if upgrading from very old 2.* versions to latest/newer versions: $ ovn-nbctl set NB_Global . name= Then restart ovn-ic daemons in all availability zones. Missing above step will result in cpu of ovn-ic active instance spike to 100%. This occurs due to null name column as ovn-ic in each availability zones repeatedly fails in commiting transaction to South bound in remote availability zones due to duplicate chassis. This will also result in manual clean up remote availability zones gateway chassis of type interconnection in local availability zone causing data plane impact. Fix these issues by below command on each availability zone part of upgrade from very old 2.* versions after stopping ovn-ic on all availability zones: $ ovn-nbctl set NB_Global . name= $ ovn-sbctl chassis-del Upgrade OVN Integration ~~~~~~~~~~~~~~~~~~~~~~~ Lastly, you may also want to upgrade integration with OVN that you may be using. For example, this could be the OpenStack Neutron driver or ovn-kubernetes. OVN's northbound database schema is a backwards compatible interface, so you should be able to safely complete an OVN upgrade before upgrading any integration in use. .. LINKS .. _ovn-controller man page: https://www.ovn.org/support/dist-docs/ovn-controller.8.html .. _version pinning check in the incremental processing engine: https://github.com/ovn-org/ovn/commit/c2eeb2c98ea8 ovn-25.09.0~git20250813.23884f5/Documentation/intro/install/windows.rst000066400000000000000000000017211504532661100250040ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================= OVN on Windows ======================= TODO ---- * This document needs to be updated. ovn-25.09.0~git20250813.23884f5/Documentation/ref/000077500000000000000000000000001504532661100205325ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/ref/index.rst000066400000000000000000000073271504532661100224040ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =============== Reference Guide =============== Man Pages --------- .. TODO(stephenfin): Remove the below notice once everything is converted to rST The following man pages are written in rST and converted to roff at compile time: .. toctree:: :maxdepth: 3 ovn-sim.1 The remainder are still in roff format can be found below: .. list-table:: * - ovn-architecture(7) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-controller(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-controller-vtep(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-ctl(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-nb(5) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-nbctl(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-northd(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-sb(5) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-sbctl(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ * - ovn-trace(8) - `(pdf) `__ - `(html) `__ - `(plain text) `__ ovn-25.09.0~git20250813.23884f5/Documentation/ref/ovn-sim.1.rst000066400000000000000000000074211504532661100230170ustar00rootroot00000000000000======= ovn-sim ======= Synopsis ======== ``ovn-sim`` [*option*]... [*script*]... Description =========== ``ovn-sim`` is a wrapper script that adds ovn related commands on top of ``ovs-sim``. ``ovs-sim`` provides a convenient environment for running one or more Open vSwitch instances and related software in a sandboxed simulation environment. To use ``ovn-sim``, first build Open vSwitch, then invoke it directly from the build directory, e.g.:: git clone https://github.com/openvswitch/ovs.git cd ovs ./boot.sh && ./configure && make cd .. git clone https://github.com/ovn-org/ovn.git cd ovn ./boot.sh && ./configure --with-ovs-source=${PWD}/../ovs make utilities/ovn-sim See documentation on ``ovs-sim`` for info on simulator, including the parameters you can use. OVN Commands ------------ These commands interact with OVN, the Open Virtual Network. ``ovn_start`` [*options*] Creates and initializes the central OVN databases (both ``ovn-sb(5)`` and ``ovn-nb(5)``) and starts an instance of ``ovsdb-server`` for each one. Also starts an instance of ``ovn-northd``. The following options are available: ``--nbdb-model`` *model* Uses the given database model for the northbound database. The *model* may be ``standalone`` (the default), ``backup``, or ``clustered``. ``--nbdb-servers`` *n* For a clustered northbound database, the number of servers in the cluster. The default is 3. ``--sbdb-model`` *model* Uses the given database model for the southbound database. The *model* may be ``standalone`` (the default), ``backup``, or ``clustered``. ``--sbdb-servers`` *n* For a clustered southbound database, the number of servers in the cluster. The default is 3. ``ovn_attach`` *network* *bridge* *ip* [*masklen*] First, this command attaches bridge to interconnection network network, just like ``net_attach`` *network* *bridge*. Second, it configures (simulated) IP address *ip* (with network mask length *masklen*, which defaults to 24) on *bridge*. Finally, it configures the Open vSwitch database to work with OVN and starts ``ovn-controller``. Examples ======== Simulating hypervisors, starting ovn controller (via ovn_attach) and adding a logical port on each one of them:: ovn_start ovn-nbctl ls-add lsw0 net_add n1 for i in 0 1; do sim_add hv$i as hv$i ovs-vsctl add-br br-phys ovn_attach n1 br-phys 192.168.0.`expr $i + 1` ovs-vsctl add-port br-int vif$i -- \ set Interface vif$i external-ids:iface-id=lp$i ovn-nbctl lsp-add lsw0 lp$i ovn-nbctl lsp-set-addresses lp$i f0:00:00:00:00:0$i done Here’s a primitive OVN "scale test" (adjust the scale by changing ``n`` in the first line):: n=200; export n ovn_start --sbdb-model=clustered net_add n1 ovn-nbctl ls-add br0 for i in `seq $n`; do (sim_add hv$i as hv$i ovs-vsctl add-br br-phys y=$(expr $i / 256) x=$(expr $i % 256) ovn_attach n1 br-phys 192.168.$y.$x ovs-vsctl add-port br-int vif$i -- \ set Interface vif$i external-ids:iface-id=lp$i) & case $i in *50|*00) echo $i; wait ;; esac done wait for i in `seq $n`; do yy=$(printf %02x $(expr $i / 256)) xx=$(printf %02x $(expr $i % 256)) ovn-nbctl lsp-add br0 lp$i ovn-nbctl lsp-set-addresses lp$i f0:00:00:00:$yy:$xx done When the scale test has finished initializing, you can watch the logical ports come up with a command like this:: watch 'for i in `seq $n`; do \ if test `ovn-nbctl lsp-get-up lp$i` != up; then echo $i; fi; done' ovn-25.09.0~git20250813.23884f5/Documentation/requirements.txt000066400000000000000000000000471504532661100232430ustar00rootroot00000000000000sphinx>=1.1 sphinx_rtd_theme>=1.0,<2.0 ovn-25.09.0~git20250813.23884f5/Documentation/topics/000077500000000000000000000000001504532661100212575ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/topics/high-availability.rst000066400000000000000000000500151504532661100254010ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================================== OVN Gateway High Availability Plan ================================== :: OVN Gateway +---------------------------+ | | | External Network | | | +-------------^-------------+ | | +-----------+ | | | Gateway | | | +-----------+ ^ | | +-------------v-------------+ | | | OVN Virtual Network | | | +---------------------------+ The OVN gateway is responsible for shuffling traffic between the tunneled overlay network (governed by ovn-northd), and the legacy physical network. In a naive implementation, the gateway is a single x86 server, or hardware VTEP. For most deployments, a single system has enough forwarding capacity to service the entire virtualized network, however, it introduces a single point of failure. If this system dies, the entire OVN deployment becomes unavailable. To mitigate this risk, an HA solution is critical -- by spreading responsibility across multiple systems, no single server failure can take down the network. An HA solution is both critical to the manageability of the system, and extremely difficult to get right. The purpose of this document, is to propose a plan for OVN Gateway High Availability which takes into account our past experience building similar systems. It should be considered a fluid changing proposal, not a set-in-stone decree. .. note:: This document describes a range of options OVN could take to provide high availability for gateways. The current implementation provides L3 gateway high availability by the "Router Specific Active/Backup" approach described in this document. Basic Architecture ------------------ In an OVN deployment, the set of hypervisors and network elements operating under the guidance of ovn-northd are in what's called "logical space". These servers use VXLAN or Geneve to communicate, oblivious to the details of the underlying physical network. When these systems need to communicate with legacy networks, traffic must be routed through a Gateway which translates from OVN controlled tunnel traffic, to raw physical network traffic. Since the gateway is typically the only system with a connection to the physical network all traffic between logical space and the WAN must travel through it. This makes it a critical single point of failure -- if the gateway dies, communication with the WAN ceases for all systems in logical space. To mitigate this risk, multiple gateways should be run in a "High Availability Cluster" or "HA Cluster". The HA cluster will be responsible for performing the duties of a gateways, while being able to recover gracefully from individual member failures. :: OVN Gateway HA Cluster +---------------------------+ | | | External Network | | | +-------------^-------------+ | | +----------------------v----------------------+ | | | High Availability Cluster | | | | +-----------+ +-----------+ +-----------+ | | | | | | | | | | | Gateway | | Gateway | | Gateway | | | | | | | | | | | +-----------+ +-----------+ +-----------+ | +----------------------^----------------------+ | | +-------------v-------------+ | | | OVN Virtual Network | | | +---------------------------+ L2 vs L3 High Availability ~~~~~~~~~~~~~~~~~~~~~~~~~~ In order to achieve this goal, there are two broad approaches one can take. The HA cluster can appear to the network like a giant Layer 2 Ethernet Switch, or like a giant IP Router. These approaches are called L2HA, and L3HA respectively. L2HA allows ethernet broadcast domains to extend into logical space, a significant advantage, but this comes at a cost. The need to avoid transient L2 loops during failover significantly complicates their design. On the other hand, L3HA works for most use cases, is simpler, and fails more gracefully. For these reasons, it is suggested that OVN supports an L3HA model, leaving L2HA for future work (or third party VTEP providers). Both models are discussed further below. L3HA ---- In this section, we'll work through a basic simple L3HA implementation, on top of which we'll gradually build more sophisticated features explaining their motivations and implementations as we go. Naive active-backup ~~~~~~~~~~~~~~~~~~~ Let's assume that there are a collection of logical routers which a tenant has asked for, our task is to schedule these logical routers on one of N gateways, and gracefully redistribute the routers on gateways which have failed. The absolute simplest way to achieve this is what we'll call "naive-active-backup". :: Naive Active Backup HA Implementation +----------------+ +----------------+ | Leader | | Backup | | | | | | A B C | | | | | | | +----+-+-+-+----++ +-+--------------+ ^ ^ ^ ^ | | | | | | | | | | | | +-+------+---+ + + + + | ovn-northd | Traffic +------------+ In a naive active-backup, one of the Gateways is chosen (arbitrarily) as a leader. All logical routers (A, B, C in the figure), are scheduled on this leader gateway and all traffic flows through it. ovn-northd monitors this gateway via OpenFlow echo requests (or some equivalent), and if the gateway dies, it recreates the routers on one of the backups. This approach basically works in most cases and should likely be the starting point for OVN -- it's strictly better than no HA solution and is a good foundation for more sophisticated solutions. That said, it's not without it's limitations. Specifically, this approach doesn't coordinate with the physical network to minimize disruption during failures, and it tightly couples failover to ovn-northd (we'll discuss why this is bad in a bit), and wastes resources by leaving backup gateways completely unutilized. Router Failover +++++++++++++++ When ovn-northd notices the leader has died and decides to migrate routers to a backup gateway, the physical network has to be notified to direct traffic to the new gateway. Otherwise, traffic could be blackholed for longer than necessary making failovers worse than they need to be. For now, let's assume that OVN requires all gateways to be on the same IP subnet on the physical network. If this isn't the case, gateways would need to participate in routing protocols to orchestrate failovers, something which is difficult and out of scope of this document. Since all gateways are on the same IP subnet, we simply need to worry about updating the MAC learning tables of the Ethernet switches on that subnet. Presumably, they all have entries for each logical router pointing to the old leader. If these entries aren't updated, all traffic will be sent to the (now defunct) old leader, instead of the new one. In order to mitigate this issue, it's recommended that the new gateway sends a Reverse ARP (RARP) onto the physical network for each logical router it now controls. A Reverse ARP is a benign protocol used by many hypervisors when virtual machines migrate to update L2 forwarding tables. In this case, the ethernet source address of the RARP is that of the logical router it corresponds to, and its destination is the broadcast address. This causes the RARP to travel to every L2 switch in the broadcast domain, updating forwarding tables accordingly. This strategy is recommended in all failover mechanisms discussed in this document -- when a router newly boots on a new leader, it should RARP its MAC address. Controller Independent Active-backup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: Controller Independent Active-Backup Implementation +----------------+ +----------------+ | Leader | | Backup | | | | | | A B C | | | | | | | +----------------+ +----------------+ ^ ^ ^ ^ | | | | | | | | + + + + Traffic The fundamental problem with naive active-backup, is it tightly couples the failover solution to ovn-northd. This can significantly increase downtime in the event of a failover as the (often already busy) ovn-northd controller has to recompute state for the new leader. Worse, if ovn-northd goes down, we can't perform gateway failover at all. This violates the principle that control plane outages should have no impact on dataplane functionality. In a controller independent active-backup configuration, ovn-northd is responsible for initial configuration while the HA cluster is responsible for monitoring the leader, and failing over to a backup if necessary. ovn-northd sets HA policy, but doesn't actively participate when failovers occur. Of course, in this model, ovn-northd is not without some responsibility. Its role is to pre-plan what should happen in the event of a failure, leaving it to the individual switches to execute this plan. It does this by assigning each gateway a unique leadership priority. Once assigned, it communicates this priority to each node it controls. Nodes use the leadership priority to determine which gateway in the cluster is the active leader by using a simple metric: the leader is the gateway that is healthy, with the highest priority. If that gateway goes down, leadership falls to the next highest priority, and conversely, if a new gateway comes up with a higher priority, it takes over leadership. Thus, in this model, leadership of the HA cluster is determined simply by the status of its members. Therefore if we can communicate the status of each gateway to each transport node, they can individually figure out which is the leader, and direct traffic accordingly. Tunnel Monitoring +++++++++++++++++ Since in this model leadership is determined exclusively by the health status of member gateways, a key problem is how do we communicate this information to the relevant transport nodes. Luckily, we can do this fairly cheaply using tunnel monitoring protocols like BFD. The basic idea is pretty straightforward. Each transport node maintains a tunnel to every gateway in the HA cluster (not just the leader). These tunnels are monitored using the BFD protocol to see which are alive. Given this information, hypervisors can trivially compute the highest priority live gateway, and thus the leader. In practice, this leadership computation can be performed trivially using the bundle or group action. Rather than using OpenFlow to simply output to the leader, all gateways could be listed in an active-backup bundle action ordered by their priority. The bundle action will automatically take into account the tunnel monitoring status to output the packet to the highest priority live gateway. Inter-Gateway Monitoring ++++++++++++++++++++++++ One somewhat subtle aspect of this model, is that failovers are not globally atomic. When a failover occurs, it will take some time for all hypervisors to notice and adjust accordingly. Similarly, if a new high priority Gateway comes up, it may take some time for all hypervisors to switch over to the new leader. In order to avoid confusing the physical network, under these circumstances it's important for the backup gateways to drop traffic they've received erroneously. In order to do this, each Gateway must know whether or not it is, in fact active. This can be achieved by creating a mesh of tunnels between gateways. Each gateway monitors the other gateways its cluster to determine which are alive, and therefore whether or not that gateway happens to be the leader. If leading, the gateway forwards traffic normally, otherwise it drops all traffic. We should note that this method works well under the assumption that there are no inter-gateway connectivity failures, in such case this method would fail to elect a single leader. The simplest example is two gateways which stop seeing each other but can still reach the hypervisors. Protocols like VRRP or CARP have the same issue. A mitigation for this type of failure mode could be achieved by having all network elements (hypervisors and gateways) periodically share their link status to other endpoints. Gateway Leadership Resignation ++++++++++++++++++++++++++++++ Sometimes a gateway may be healthy, but still may not be suitable to lead the HA cluster. This could happen for several reasons including: * The physical network is unreachable * BFD (or ping) has detected the next hop router is unreachable * The Gateway recently booted and isn't fully configured In this case, the Gateway should resign leadership by holding its tunnels down using the ``other_config:cpath_down`` flag. This indicates to participating hypervisors and Gateways that this gateway should be treated as if it's down, even though its tunnels are still healthy. Router Specific Active-Backup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: Router Specific Active-Backup +----------------+ +----------------+ | | | | | A C | | B D E | | | | | +----------------+ +----------------+ ^ ^ ^ ^ | | | | | | | | + + + + Traffic Controller independent active-backup is a great advance over naive active-backup, but it still has one glaring problem -- it under-utilizes the backup gateways. In ideal scenario, all traffic would split evenly among the live set of gateways. Getting all the way there is somewhat tricky, but as a step in the direction, one could use the "Router Specific Active-Backup" algorithm. This algorithm looks a lot like active-backup on a per logical router basis, with one twist. It chooses a different active Gateway for each logical router. Thus, in situations where there are several logical routers, all with somewhat balanced load, this algorithm performs better. Implementation of this strategy is quite straightforward if built on top of basic controller independent active-backup. On a per logical router basis, the algorithm is the same, leadership is determined by the liveness of the gateways. The key difference here is that the gateways must have a different leadership priority for each logical router. These leadership priorities can be computed by ovn-northd just as they had been in the controller independent active-backup model. Once we have these per logical router priorities, they simply need be communicated to the members of the gateway cluster and the hypervisors. The hypervisors in particular, need simply have an active-backup bundle action (or group action) per logical router listing the gateways in priority order for *that router*, rather than having a single bundle action shared for all the routers. Additionally, the gateways need to be updated to take into account individual router priorities. Specifically, each gateway should drop traffic of backup routers it's running, and forward traffic of active gateways, instead of simply dropping or forwarding everything. This should likely be done by having ovn-controller recompute OpenFlow for the gateway, though other options exist. The final complication is that ovn-northd's logic must be updated to choose these per logical router leadership priorities in a more sophisticated manner. It doesn't matter much exactly what algorithm it chooses to do this, beyond that it should provide good balancing in the common case. I.E. each logical routers priorities should be different enough that routers balance to different gateways even when failures occur. Preemption ++++++++++ In an active-backup setup, one issue that users will run into is that of gateway leader preemption. If a new Gateway is added to a cluster, or for some reason an existing gateway is rebooted, we could end up in a situation where the newly activated gateway has higher priority than any other in the HA cluster. In this case, as soon as that gateway appears, it will preempt leadership from the currently active leader causing an unnecessary failover. Since failover can be quite expensive, this preemption may be undesirable. The controller can optionally avoid preemption by cleverly tweaking the leadership priorities. For each router, new gateways should be assigned priorities that put them second in line or later when they eventually come up. Furthermore, if a gateway goes down for a significant period of time, its old leadership priorities should be revoked and new ones should be assigned as if it's a brand new gateway. Note that this should only happen if a gateway has been down for a while (several minutes), otherwise a flapping gateway could have wide ranging, unpredictable, consequences. Note that preemption avoidance should be optional depending on the deployment. One necessarily sacrifices optimal load balancing to satisfy these requirements as new gateways will get no traffic on boot. Thus, this feature represents a trade-off which must be made on a per installation basis. Fully Active-Active HA ~~~~~~~~~~~~~~~~~~~~~~ :: Fully Active-Active HA +----------------+ +----------------+ | | | | | A B C D E | | A B C D E | | | | | +----------------+ +----------------+ ^ ^ ^ ^ | | | | | | | | + + + + Traffic The final step in L3HA is to have true active-active HA. In this scenario each router has an instance on each Gateway, and a mechanism similar to ECMP is used to distribute traffic evenly among all instances. This mechanism would require Gateways to participate in routing protocols with the physical network to attract traffic and alert of failures. It is out of scope of this document, but may eventually be necessary. L2HA ---- L2HA is very difficult to get right. Unlike L3HA, where the consequences of problems are minor, in L2HA if two gateways are both transiently active, an L2 loop triggers and a broadcast storm results. In practice to get around this, gateways end up implementing an overly conservative "when in doubt drop all traffic" policy, or they implement something like MLAG. MLAG has multiple gateways work together to pretend to be a single L2 switch with a large LACP bond. In principle, it's the right solution to the problem as it solves the broadcast storm problem, and has been deployed successfully in other contexts. That said, it's difficult to get right and not recommended. ovn-25.09.0~git20250813.23884f5/Documentation/topics/index.rst000066400000000000000000000027121504532661100231220ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========= Deep Dive ========= How OVN is implemented and, where necessary, why it was implemented that way. OVN --- .. toctree:: :maxdepth: 2 integration.rst high-availability role-based-access-control ovn-news-2.8 vif-plug-providers/index testing .. list-table:: * - ovn-architecture(7) - `(pdf) `__ - `(html) `__ - `(plain text) `__ ovn-25.09.0~git20250813.23884f5/Documentation/topics/integration.rst000066400000000000000000000117661504532661100243470ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========================================= Integration Guide for Centralized Control ========================================= HA for OVN DB servers using pacemaker ------------------------------------- The ovsdb servers can work in either active or backup mode. In backup mode, db server will be connected to an active server and replicate the active servers contents. At all times, the data can be transacted only from the active server. When the active server dies for some reason, entire OVN operations will be stalled. `Pacemaker `__ is a cluster resource manager which can manage a defined set of resource across a set of clustered nodes. Pacemaker manages the resource with the help of the resource agents. One among the resource agent is `OCF `__ OCF is nothing but a shell script which accepts a set of actions and returns an appropriate status code. With the help of the OCF resource agent ovn/utilities/ovndb-servers.ocf, one can defined a resource for the pacemaker such that pacemaker will always maintain one running active server at any time. After creating a pacemaker cluster, use the following commands to create one active and multiple backup servers for OVN databases:: $ pcs resource create ovndb_servers ocf:ovn:ovndb-servers \ master_ip=x.x.x.x \ ovn_ctl= \ op monitor interval="10s" \ op monitor role=Master interval="15s" $ pcs resource master ovndb_servers-master ovndb_servers \ meta notify="true" The `master_ip` and `ovn_ctl` are the parameters that will be used by the OCF script. `ovn_ctl` is optional, if not given, it assumes a default value of /usr/share/openvswitch/scripts/ovn-ctl. `master_ip` is the IP address on which the active database server is expected to be listening, the slave node uses it to connect to the master node. You can add the optional parameters 'nb_master_port', 'nb_master_protocol', 'sb_master_port', 'sb_master_protocol' to set the protocol and port. Whenever the active server dies, pacemaker is responsible to promote one of the backup servers to be active. Both ovn-controller and ovn-northd needs the ip-address at which the active server is listening. With pacemaker changing the node at which the active server is run, it is not efficient to instruct all the ovn-controllers and the ovn-northd to listen to the latest active server's ip-address. This problem can be solved by two ways: 1. By using a native ocf resource agent ``ocf:heartbeat:IPaddr2``. The IPAddr2 resource agent is just a resource with an ip-address. When we colocate this resource with the active server, pacemaker will enable the active server to be connected with a single ip-address all the time. This is the ip-address that needs to be given as the parameter while creating the `ovndb_servers` resource. Use the following command to create the IPAddr2 resource and colocate it with the active server:: $ pcs resource create VirtualIP ocf:heartbeat:IPaddr2 ip=x.x.x.x \ op monitor interval=30s $ pcs constraint order promote ovndb_servers-master then VirtualIP $ pcs constraint colocation add VirtualIP with master ovndb_servers-master \ score=INFINITY 2. Using load balancer vip ip as a master_ip. In order to use this feature, one needs to use listen_on_master_ip_only to no. Current code for load balancer have been tested to work with tcp protocol and needs to be tested/enchanced for ssl/tls. Using load balancer, standby nodes will not listen on nb and sb db ports so that load balancer will always communicate to the active node and all the traffic will be sent to active node only. Standby will continue to sync using LB VIP IP in this case. Use the following command to create pcs resource using LB VIP IP:: $ pcs resource create ovndb_servers ocf:ovn:ovndb-servers \ master_ip="" \ listen_on_master_ip_only="no" \ ovn_ctl= \ op monitor interval="10s" \ op monitor role=Master interval="15s" $ pcs resource master ovndb_servers-master ovndb_servers \ meta notify="true" ovn-25.09.0~git20250813.23884f5/Documentation/topics/ovn-news-2.8.rst000066400000000000000000000340241504532661100240750ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =============================== What's New with OVS and OVN 2.8 =============================== This document is about what was added in Open vSwitch 2.8, which was released at the end of August 2017, concentrating on the new features in OVN. It also covers some of what is coming up in Open vSwitch and OVN 2.9, which is due to be released in February 2018. OVN has many features, and this document does not cover every new or enhanced feature (but contributions are welcome). This document assumes a basic familiarity with Open vSwitch, OVN, and their associated tools. For more information, please refer to the Open vSwitch and OVN documentation, such as the ``ovn-architecture``\(7) manpage. Debugging and Troubleshooting ----------------------------- Before version 2.8, Open vSwitch command-line tools were far more painful to use than they needed to be. This section covers the improvements made to the CLI in the 2.8 release. User-Hostile UUIDs ~~~~~~~~~~~~~~~~~~ The OVN CLI, through ``ovn-nbctl``, ``ovn-nbctl``, and ``ovn-trace``, used full-length UUIDs almost everywhere. It didn't even provide any assistance with completion, etc., which in practice meant always cutting and pasting UUIDs from one command or window to another. This problem wasn't limited to the places where one would expect to have to see or use a UUID, either. In many places where one would expect to be able to use a network, router, or port name, a UUID was required instead. In many places where one would want to see a name, the UUID was displayed instead. More than anything else, these shortcomings made the CLI user-hostile. There was an underlying problem that the southbound database didn't actually contain all the information needed to provide a decent user interface. In some cases, for example, the human-friendly names that one would want to use for entities simply weren't part of the database. These names weren't necessary for correctness, only for usability. OVN 2.8 eased many of these problems. Most parts of the CLI now allow the user to abbreviate UUIDs, as long as the abbreviations are unique within the database. Some parts of the CLI where full-length UUIDs make output hard to read now abbreviate them themselves. Perhaps more importantly, in many places the OVN CLI now displays and accepts human-friendly names for networks, routers, ports, and other entities. In the places where the names were not previously available, OVN (through ``ovn-northd``) now copies the names into the southbound database. The CLIs for layers below OVN, at the OpenFlow and datapath layers with ``ovs-ofctl`` and ``ovs-dpctl``, respectively, had some similar problems in which numbers were used for entities that had human-friendly names. Open vSwitch 2.8 also solves some of those problems. Other than that, the most notable enhancement in this area was the ``--no-stats`` option to ``ovs-ofctl dump-flows``, which made that command's output more readable for the cases where per-flow statistics were not interesting to the reader. Connections Between Levels ~~~~~~~~~~~~~~~~~~~~~~~~~~ OVN and Open vSwitch work almost like a stack of compilers: the OVN Neutron plugin translates Neutron configuration into OVN northbound configuration, which ``ovn-northd`` translates into logical flows, which ``ovn-controller`` translates into OpenFlow flows, which ``ovs-vswitchd`` translates into datapath flows. For debugging and troubleshooting it is often necessary to understand exactly how these translations work. The relationship from a logical flow to its OpenFlow flows, or in the other direction, from an OpenFlow flow back to the logical flow that produced it, was often of particular interest, but OVN didn't provide good tools for the job. OVN 2.8 added some new features that ease these jobs. ``ovn-sbctl lflow-list`` has a new option ``--ovs`` that lists the OpenFlow flows on a particular chassis that were generated from the logical flows that it lists. ``ovn-trace`` also added a similar ``--ovs`` option that applies to the logical flows it traces. In the other direction, OVN 2.8 added a new utility ``ovn-detrace`` that, given an Open vSwitch trace of OpenFlow flows, annotates it with the logical flows that yielded those OpenFlow flows. Distributed Firewall ~~~~~~~~~~~~~~~~~~~~ OVN supports a distributed firewall with stateful connection tracking to ensure that only packets for established connections, or those that the configuration explicitly allows, can ingress a given VM or container. Neutron uses this feature by default. Most packets in an OpenStack environment pass through it twice, once after egress from the packet's source VM and once before ingress into its destination VM. Before OVN 2.8, the ``ovn-trace`` program, which shows the path of a packet through an OVN logical network, did not support the logical firewall, which in practice made it almost useless for Neutron. In OVN 2.8, ``ovn-trace`` adds support for the logical firewall. By default it assumes that packets are part of an established connection, which is usually what the user wants as part of the trace. It also accepts command-line options to override that assumption, which allows the user to discover the treatment of packets that the firewall should drop. At the next level deeper, prior to Open vSwitch 2.8, the OpenFlow tracing command ``ofproto/trace`` also supported neither the connection tracking feature underlying the OVN distributed firewall nor the "recirculation" feature that accompanied it. This meant that, even if the user tried to look deeper into the distributed firewall mechanism, he or she would encounter a further roadblock. Open vSwitch 2.8 added support for both of these features as well. Summary Display ~~~~~~~~~~~~~~~ ``ovn-nbctl show`` and ``ovn-sbctl show``, for showing an overview of the OVN configuration, didn't show a lot of important information. OVN adds some more useful information here. DNS, and IPAM ------------- OVN 2.8 adds a built-in DNS server designed for assigning names to VMs and containers within an OVN logical network. DNS names are assigned using records in the OVN northbound database and, like other OVN features, translated into logical flows at the OVN southbound layer. DNS requests directed to the OVN DNS server never leave the hypervisor from which the request is sent; instead, OVN processes and replies to the request from its ``ovn-controller`` local agent. The OVN DNS server is not a general-purpose DNS server and cannot be used for that purpose. OVN includes simple built-in support for IP address management (IPAM), in which OVN assigns IP addresses to VMs or containers from a pool or pools of IP addresses delegated to it by the administrator. Before OVN 2.8, OVN IPAM only supported IPv4 addresses; OVN 2.8 adds support for IPv6. OVN 2.8 also enhances the address pool support to allow specific addresses to be excluded. Neutron assigns IP addresses itself and does not use OVN IPAM. High Availability ----------------- As a distributed system, in OVN a lot can go wrong. As OVN advances, it adds redundancy in places where currently a single failure could disrupt the functioning of the system as a whole. OVN 2.8 adds two new kinds of high availability. ovn-northd HA ~~~~~~~~~~~~~ The ``ovn-northd`` program sits between the OVN northbound and southbound databases and translates from a logical network configuration into logical flows. If ``ovn-northd`` itself or the host on which it runs fails, then updates to the OVN northbound configuration will not propagate to the hypervisors and the OVN configuration freezes in place until ``ovn-northd`` restarts. OVN 2.8 adds support for active-backup HA to ``ovn-northd``. When more than one ``ovn-northd`` instance runs, it uses an OVSDB locking feature to automatically choose a single active instance. When that instance dies or becomes nonresponsive, the OVSDB server automatically choose one of the remaining instance(s) to take over. L3 Gateway HA ~~~~~~~~~~~~~ In OVN 2.8, multiple chassis may now be specified for L3 gateways. When more than one chassis is specified, OVN manages high availability for that gateway. Each hypervisor uses the BFD protocol to keep track of the gateway nodes that are currently up. At any given time, a hypervisor uses the highest-priority gateway node that is currently up. OVSDB ----- The OVN architecture relies heavily on OVSDB, the Open vSwitch database, for hosting the northbound and southbound databases. OVSDB was originally selected for this purpose because it was already used in Open vSwitch for configuring OVS itself and, thus, it was well integrated with OVS and well supported in C and Python, the two languages that are used in Open vSwitch. OVSDB was well designed for its original purpose of configuring Open vSwitch. It supports ACID transactions, has a small, efficient server, a flexible schema system, and good support for troubleshooting and debugging. However, it lacked several features that are important for OVN but not for Open vSwitch. As OVN advances, these missing features have become more and more of a problem. One option would be to switch to a different database that already has many of these features, but despite a careful search, no ideal existing database was identified, so the project chose instead to improve OVSDB where necessary to bring it up to speed. The following sections talk more about recent and future improvements. High Availability ~~~~~~~~~~~~~~~~~ When ``ovsdb-server`` was only used for OVS configuration, high availability was not important. ``ovsdb-server`` was capable of restarting itself automatically if it crashed, and if the whole system went down then Open vSwitch itself was dead too, so the database server's failure was not important. In contrast, the northbound and southbound databases are centralized components of a distributed system, so it is important that they not be a single point of failure for the system as a whole. In released versions of OVN, ``ovsdb-server`` supports only "active-backup replication" across a pair of servers. This means that if one server goes down, the other can pick it back up approximately where the other one left off. The servers do not have built-in support for deciding at any given time which is the active and which the backup, so the administrator must configure an external agent to do this management. Active-backup replication is not entirely satisfactory, for multiple reasons. Replication is only approximate. Configuring the external agent requires extra work. There is no benefit from the backup server except when the active server fails. At most two servers can be used. A new form of high availability for OVSDB is under development for the OVN 2.9 release, based on the Raft algorithm for distributed consensus. Whereas replication uses two servers, clustering using Raft requires three or more (typically an odd number) and continues functioning as long as more than half of the servers are up. The clustering implementation is built into ``ovsdb-server`` and does not require an external agent. Clustering preserves the ACID properties of the database, so that a transaction that commits is guaranteed to persist. Finally, reads (which are the bulk of the OVN workload) scale with the size of the cluster, so that adding more servers should improve performance as the number of hypervisors in an OVN deployment increases. As of this writing, OVSDB support for clustering is undergoing development and early deployment testing. RBAC security ~~~~~~~~~~~~~ Until Open vSwitch 2.8, ``ovsdb-server`` had little support for access control within a database. If an OVSDB client could modify the database at all, it could make arbitrary changes. This was sufficient for most uses case to that point. Hypervisors in an OVN deployment need access to the OVN southbound database. Most of their access is reads, to find out about the OVN configuration. Hypervisors do need some write access to the southbound database, primarily to let the other hypervisors know what VMs and containers they are running and how to reach them. Thus, OVN gives all of the hypervisors in the OVN deployment write access to the OVN southbound database. This is fine when all is well, but if any of the hypervisors were compromised then they could disrupt the entire OVN deployment by corrupting the database. The OVN developers considered a few ways to solve this problem. One way would be to introduce a new central service (perhaps in ``ovn-northd``) that provided only the kinds of writes that the hypervisors legitimately need, and then grant hypervisors direct access to the southbound database only for reads. But ultimately the developers decided to introduce a new form of more access control for OVSDB, called the OVSDB RBAC (role-based access control) feature. OVSDB RBAC allows for granular enough control over access that hypervisors can be granted only the ability to add, modify, and delete the records that relate to themselves, preventing them from corrupting the database as a whole. Further Directions ------------------ For more information about new features in OVN and Open vSwitch, please refer to the NEWS file distributed with the source tree. If you have questions about Open vSwitch or OVN features, please feel free to write to the Open vSwitch discussion mailing list at ovs-discuss@openvswitch.org. ovn-25.09.0~git20250813.23884f5/Documentation/topics/role-based-access-control.rst000066400000000000000000000104151504532661100267440ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========================= Role Based Access Control ========================= Where SSL/TLS provides authentication when connecting to an OVS database, role based access control (RBAC) provides authorization to operations performed by clients connecting to an OVS database. RBAC allows for administrators to restrict the database operations a client may perform and thus enhance the security already provided by SSL/TLS. In theory, any OVS database could define RBAC roles and permissions, but at present only the OVN southbound database has the appropriate tables defined to facilitate RBAC. Mechanics --------- RBAC is intended to supplement SSL/TLS. In order to enable RBAC, the connection to the database must use SSL/TLS. Some permissions in RBAC are granted based on the certificate common name (CN) of the connecting client. RBAC is controlled with two database tables, RBAC_Role and RBAC_Permission. The RBAC_Permission table contains records that describe a set of permissions for a given table in the database. The RBAC_Permission table contains the following columns: table The table in the database for which permissions are being described. insert_delete Describes whether insertion and deletion of records is allowed. update A list of columns that are allowed to be updated. authorization A list of column names. One of the listed columns must match the SSL/TLS certificate CN in order for the attempted operation on the table to succeed. If a key-value pair is provided, then the key is the column name, and the value is the name of a key in that column. An empty string gives permission to all clients to perform operations. The RBAC_Role table contains the following columns: name The name of the role being defined permissions A list of key-value pairs. The key is the name of a table in the database, and the value is a UUID of a record in the RBAC_Permission table that describes the permissions the role has for that table. .. note:: All tables not explicitly referenced in an RBAC_Role record are read-only In order to enable RBAC, specify the role name as an argument to the set-connection command for the database. As an example, to enable the "ovn-controller" role on the OVN southbound database, use the following command: :: $ ovn-sbctl set-connection role=ovn-controller ssl:192.168.0.1:6642 .. note:: There is currently no pre-defined role for ovn-northd. You must configure a separate listener on the OVN southbound database that ovn-northd can connect to if your deployment topology require ovn-northd to connect to a OVN southbound database instance on a remote machine. Pre-defined Roles ----------------- This section describes roles that have been defined internally by OVS/OVN. ovn-controller ~~~~~~~~~~~~~~ The ovn-controller role is specified in the OVN southbound database and is intended for use by hypervisors running the ovn-controller daemon. ovn-controller connects to the OVN southbound database mostly to read information, but there are a few cases where ovn-controller also needs to write. The ovn-controller role was designed to allow for ovn-controllers to write to the southbound database only in places where it makes sense to do so. This way, if an intruder were to take over a hypervisor running ovn-controller, it is more difficult to compromise the entire overlay network. It is strongly recommended to set the ovn-controller role for the OVN southbound database to enhance security. ovn-25.09.0~git20250813.23884f5/Documentation/topics/testing.rst000066400000000000000000000252171504532661100234750ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======= Testing ======= It is possible to test OVN using both tooling provided with Open vSwitch and using a variety of third party tooling. Built-in Tooling ---------------- OVN provides a number of different test suites and other tooling for validating basic functionality of OVN. Before running any of the tests described here, you must bootstrap, configure and build OVN as described in :doc:`/intro/install/general`. You do not need to install OVN, Open vSwitch or to build or load the kernel module to run these test suites.You do not need supervisor privilege to run these test suites. Unit Tests ~~~~~~~~~~ OVN includes a suite of self-tests. Before you submit patches upstream, we advise that you run the tests and ensure that they pass. If you add new features to OVN, then adding tests for those features will ensure your features don't break as developers modify other areas of OVN. To run all the unit tests in OVN, one at a time, run:: $ make check This takes under 5 minutes on a modern desktop system. To run all the unit tests in OVN in parallel, run:: $ make check TESTSUITEFLAGS=-j8 You can run up to eight threads. This takes under a minute on a modern 4-core desktop system. To see a list of all the available tests, run:: $ make check TESTSUITEFLAGS=--list To run only a subset of tests, e.g. test 123 and tests 477 through 484, run:: $ make check TESTSUITEFLAGS='123 477-484' Tests do not have inter-dependencies, so you may run any subset. To run tests matching a keyword, e.g. ``ovsdb``, run:: $ make check TESTSUITEFLAGS='-k ovsdb' To see a complete list of test options, run:: $ make check TESTSUITEFLAGS=--help The results of a testing run are reported in ``tests/testsuite.log``. Report report test failures as bugs and include the ``testsuite.log`` in your report. .. note:: Sometimes a few tests may fail on some runs but not others. This is usually a bug in the testsuite, not a bug in OVN itself. If you find that a test fails intermittently, please report it, since the developers may not have noticed. You can make the testsuite automatically rerun tests that fail, by adding ``RECHECK=yes`` to the ``make`` command line, e.g.:: $ make check TESTSUITEFLAGS=-j8 RECHECK=yes Debugging unit tests ++++++++++++++++++++ To initiate debugging from artifacts generated from `make check` run, set the ``OVS_PAUSE_TEST`` environment variable to 1. For example, to run test case 139 and pause on error:: $ OVS_PAUSE_TEST=1 make check TESTSUITEFLAGS='-v 139' When error occurs, above command would display something like this:: Set environment variable to use various ovs utilities export OVS_RUNDIR=/ovs/_build-gcc/tests/testsuite.dir/0139 Press ENTER to continue: And from another window, one can execute ovs-xxx commands like:: export OVS_RUNDIR=/opt/vdasari/Developer/ovs/_build-gcc/tests/testsuite.dir/0139 $ ovs-ofctl dump-ports br0 . . Once done with investigation, press ENTER to perform cleanup operation. OVS_PAUSE_TEST=1 only pauses failed tests when run with '-v' option. Tests run without '-v', or successful tests, are not paused. .. _testing-coverage: Coverage ~~~~~~~~ If the build was configured with ``--enable-coverage`` and the ``lcov`` utility is installed, you can run the testsuite and generate a code coverage report by using the ``check-lcov`` target:: $ make check-lcov All the same options are available via TESTSUITEFLAGS. For example:: $ make check-lcov TESTSUITEFLAGS='-j8 -k ovn' .. _testing-valgrind: Valgrind ~~~~~~~~ If you have ``valgrind`` installed, you can run the testsuite under valgrind by using the ``check-valgrind`` target:: $ make check-valgrind When you do this, the "valgrind" results for test ```` are reported in files named ``tests/testsuite.dir//valgrind.*``. To test the testsuite of kernel datapath under valgrind, you can use the ``check-kernel-valgrind`` target and find the "valgrind" results under directory ``tests/system-kmod-testsuite.dir/``. All the same options are available via TESTSUITEFLAGS. .. hint:: You may find that the valgrind results are easier to interpret if you put ``-q`` in ``~/.valgrindrc``, since that reduces the amount of output. Static Code Analysis ~~~~~~~~~~~~~~~~~~~~ Static Analysis is a method of debugging Software by examining code rather than actually executing it. This can be done through 'scan-build' commandline utility which internally uses clang (or) gcc to compile the code and also invokes a static analyzer to do the code analysis. At the end of the build, the reports are aggregated in to a common folder and can later be analyzed using 'scan-view'. OVN includes a Makefile target to trigger static code analysis:: $ ./boot.sh $ ./configure CC=clang # clang # or $ ./configure CC=gcc CFLAGS="-std=gnu99" # gcc $ make clang-analyze You should invoke scan-view to view analysis results. The last line of output from ``clang-analyze`` will list the command (containing results directory) that you should invoke to view the results on a browser. Datapath testing ~~~~~~~~~~~~~~~~ OVN includes a suite of tests specifically for datapath functionality. The datapath tests make some assumptions about the environment. They must be run under root privileges on a Linux system with support for network namespaces. Make sure no other Open vSwitch instance is running the test suite. These tests may take several minutes to complete, and cannot be run in parallel. To invoke the datapath testsuite with the OVS userspace datapath, run:: $ make check-system-userspace The results of the userspace testsuite appear in ``tests/system-userspace-testsuite.dir``. To invoke the datapath testsuite with the OVS kernel datapath, run:: $ make check-kernel The results of the kernel testsuite appear in ``tests/system-kmod-testsuite.dir``. The tests themselves must run as root. If you do not run ``make`` as root, then you can specify a program to get superuser privileges as ``SUDO=``, e.g. the following uses ``sudo`` (the ``-E`` option is needed to pass through environment variables):: $ make check-system-userspace SUDO='sudo -E' The testsuite creates and destroys tap devices named ``ovs-netdev`` and ``br0``. If it is interrupted during a test, then before it can be restarted, you may need to destroy these devices with commands like the following:: $ ip tuntap del dev ovs-netdev mode tap $ ip tuntap del dev br0 mode tap All the features documented under `Unit Tests`_ are available for the datapath testsuites, except that the datapath testsuites do not support running tests in parallel. It is also possible to run `retis`_ capture along with the `check-kernel` tests by setting `OVS_TEST_WITH_RETIS` environment variable to 'yes'. This can be useful for debugging the test cases. For example, the following command can be used to run the test 168 under `retis`:: $ make check-kernel OVS_TEST_WITH_RETIS=yes TESTSUITEFLAGS='168 -d' After the test is completed, the following data will be available in the test directory: * `retis.err` - standard error stream of the `retis collect`. * `retis.log` - standard output of the `retis collect`, contains all captured events in the order they appeared. * `retis.data` - raw events collected by retis, `retis sort` or other commands can be used on this file for further analysis. * `retis.sorted` - text file containing the output of `retis sort` executed on the `retis.data`, for convenience. Requires retis version 1.5 or newer. And this also requires OVS submodule to be built with `--enable-usdt-probes`. .. _retis: https://github.com/retis-org/retis Performance testing ~~~~~~~~~~~~~~~~~~~ OVN includes a suite of micro-benchmarks to aid a developer in understanding the performance impact of any changes that they are making. They can be used to help to understand the relative performance between two test runs on the same test machine, but are not intended to give the absolute performance of OVN. To invoke the performance testsuite, run:: $ make check-perf This will run all available performance tests. Some of these tests may be long-running as they need to build complex logical network topologies. In order to speed up subsequent test runs, some objects (e.g. the Northbound DB) may be cached. In order to force the tests to rebuild all these objects, run:: $ make check-perf TESTSUITEFLAGS="--rebuild" A typical workflow for a developer trying to improve the performance of OVN would be the following: 0. Optional: Modify/add a performance test to buld the topology that you are benchmarking, if required. 1. Run ``make check-perf TESTSUITEFLAGS="--rebuild"`` to generate cached databases (and complete a test run). The results of each test run are displayed on the screen at the end of the test run but are also saved in the file ``tests/perf-testsuite.dir/results``. .. note:: This step may take some time depending on the number of tests that are being rebuilt, the complexity of the tests and the performance of the test machine. If you are only using one test, you can specify the test to run by adding the test number to the ``make`` command. (e.g. ``make check-perf TESTSUITEFLAGS="--rebuild "``) 2. Run ``make check-perf`` to measure the performance metric that you are benchmarking against. If you are only using one test, you can specify the test to run by adding the test number to the ``make`` command. (e.g. ``make check-perf TESTSUITEFLAGS="--rebuild "``) 3. Modify OVN code to implement the change that you believe will improve the performance. 4. Go to Step 2. to continue making improvements. If, as a developer, you modify a performance test in a way that may change one of these cached objects, be sure to rebuild the test. The cached objects are stored under the relevant folder in ``tests/perf-testsuite.dir/cached``. ovn-25.09.0~git20250813.23884f5/Documentation/topics/vif-plug-providers/000077500000000000000000000000001504532661100250235ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/topics/vif-plug-providers/index.rst000066400000000000000000000017211504532661100266650ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================== VIF Plug Providers ================== .. toctree:: :maxdepth: 2 vif-plug-providers ovn-25.09.0~git20250813.23884f5/Documentation/topics/vif-plug-providers/vif-plug-providers.rst000066400000000000000000000230151504532661100313220ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================== VIF Plug Providers ================== Traditionally it has been the CMSes responsibility to create VIFs as part of instance life cycle, and subsequently manage plug/unplug operations on the integration bridge following the conventions described in the `Open vSwitch Integration Guide`_ for mapping of VIFs to OVN logical port. With the advent of NICs connected to multiple distinct CPUs we can have a topology where the instance runs on one host and Open vSwitch and OVN runs on a different host, the smartnic control plane CPU. The host facing interfaces will be visible to Open vSwitch and OVN as representor ports. The actions necessary for plugging and unplugging the representor port in Open vSwitch running on the smartnic control plane CPU would be the same for every CMS. Instead of every CMS having to develop their own version of an agent to do the plugging, we provide a pluggable infrastructure in OVN that allows the `ovn-controller` to perform the plugging on CMS direction. Hardware or platform specific details for initialization and lookup of representor ports is provided by an plugging provider library hosted inside or outside the core OVN repository, and linked at OVN build time. Life Cycle of an OVN plugged VIF -------------------------------- 1. CMS creates a record in the OVN Northbound Logical_Switch_Port table with the options column containing the `vif-plug-type` key with a value corresponding to the `const char *type` provided by the VIF plug provider implementation as well as a `requested-chassis` key with a value pointing at the name or hostname of the chassis it wants the VIF plugged on. Additional VIF plug provider specific key/value pairs must be provided for successful lookup. 2. `ovn-northd` looks up the name or hostname provided in the `requested-chassis` option and fills the OVN Southbound Port_Binding requested_chassis column, it also copies relevant options over to the Port_Binding record. 3. `ovn-controller` monitors Southbound Port_Binding entries with a requested_chassis column pointing at its chassis UUID. When it encounters an entry with option `vif-plug-type` and it has registered a VIF plug provider matching that type, it will act on it even if no local binding exists yet. 4. It will fill the `struct vif_plug_port_ctx_in` as defined in `lib/vif-plug.h` with `op_type` set to 'PLUG_OP_CREATE' and make a call to the VIF plug providers `vif_plug_port_prepare` callback function. VIF plug provider performs lookup and fills the `struct vif_plug_port_ctx_out` as defined in `lib/vif-plug.h`. 5. `ovn-controller` creates a port and interface record in the local OVSDB using the details provided by the VIF plug provider and also adds `external-ids:iface-id` with value matching the logical port name and `external-ids:ovn-plugged` with value matching the logical port `vif-plug-type`. When the port creation is done a call will first be made to the VIF plug providers `vif_plug_port_finish` function and then to the `vif_plug_port_ctx_destroy` function to free any memory allocated by the VIF plug implementation. 6. The Open vSwitch vswitchd will assign a ofport to the newly created interface and on the next `ovn-controller` main loop iteration flows will be installed. 7. On each main loop iteration the `ovn-controller` will in addition to normal flow processing make a call to the VIF plug provider again similar to the first creation in case anything needs updating for the interface record. 8. The port will be unplugged when an event occurs which would make the `ovn-controller` release a logical port, for example the Logical_Switch_Port and Port_Binding entry disappearing from the database or its `requested_chassis` column being pointed to a different chassis. The VIF plug provider interface ------------------------------- The interface between internals of OVN and a VIF plug provider is a set of callbacks as defined by the `struct vif_plug_class` in `lib/vif-plug-provider.h`. It is important to note that these callbacks will be called in the critical path of the `ovn-controller` processing loop, so care must be taken to make the implementation as efficient as possible, and under no circumstance can any of the callback functions make calls that block. On `ovn-controller` startup, VIF plug providers made available at build time will be registered by the identifier provided in the `const char *type` pointer, at this time the `init` function pointer will be called if it is non-NULL. > **Note**: apart from the `const char *type` pointer, no attempt will be made to access VIF plug provider data or functions before the call to the `init` has been made. On `ovn-controller` exit, the VIF plug providers registered in the above mentioned procedure will have their `destroy` function pointer called if it is non-NULL. If the VIF plug provider has internal lookup tables that need to be maintained they can define a `run` function which will be called as part of the `ovn-controller` main loop. If there are any changes encountered the function should return 'true' to signal that further processing is necessary, 'false' otherwise. On update of Interface records the `ovn-controller` will pass on a `sset` to the `ovsport_update_iface` function containing options the plug implementation finds pertinent to maintain for successful operation. This `sset` is retrieved by making a call to the plug implementation `vif_plug_get_maintained_iface_options` function pointer if it is non-NULL. This allows presence of other users of the OVSDB maintaining a different set of options on the same set of Interface records without wiping out their changes. Before creating or updating an existing interface record the VIF plug provider `vif_plug_port_prepare` function pointer will be called with valid pointers to `struct vif_plug_port_ctx_in` and `struct vif_plug_port_ctx_out` data structures. If the VIF plug provider implementation is able to perform lookup it should fill the `struct vif_plug_port_ctx_out` data structure and return 'true'. The `ovn-controller` will then create or update the port/interface records and then call `vif_plug_port_finish` when the transactions commits and `vif_plug_port_ctx_destroy` to free any allocated memory. If the VIF plug provider implementation is unable to perform lookup or prepare the desired resource at this time, it should return 'false' which will tell the `ovn-controller` to not plug the port, in this case it will not call `vif_plug_port_finish` nor `vif_plug_port_ctx_destroy`. > **Note**: The VIF plug provider implementation should exhaust all non-blocking options to succeed with lookup from within the `vif_plug_port_prepare` handler, including refreshing lookup tables if necessary. Before removing port and interface records previously plugged by the `ovn-controller` as identified by presence of the Interface `external-ids:ovn-plugged` key, the `ovn-controller` will look up the `vif-plug-type` from `external-ids:ovn-plugged`, fill `struct vif_plug_port_ctx_in` with `op_type` set to 'PLUG_OP_REMOVE' and make a call to `vif_plug_port_prepare`. After the port and interface has been removed a call will be made to `vif_plug_port_finish`. Both calls will be made with the pointer to `vif_plug_port_ctx_out` set to 'NULL', and no call will be made to `vif_plug_port_ctx_destroy`. Building with in-tree VIF plug providers ---------------------------------------- VIF plug providers hosted in the OVN repository live under `lib/vif-plug-providers`: To enable them, provide the `--enable-vif-plug-providers` command line option to the configure script when building OVN. Building with an externally provided VIF plug provider ------------------------------------------------------ There is also infrastructure in place to support linking OVN with an externally built VIF plug provider. This external VIF plug provider must define a NULL-terminated array of pointers to `struct vif_plug_class` data structures named `vif_plug_provider_classes`. Example: .. code-block:: none const struct vif_plug_class *vif_plug_provider_classes[] = { &vif_plug_foo, NULL, }; The name of the repository for the external VIF plug provider should be the same as the name of the library it produces, and the built library artifact should be placed in lib/.libs. Example: .. code-block:: none ovn-vif-foo/ ovn-vif-foo/lib/.libs/libovn-vif-foo.la To enable such a VIF plug provider provide the `--with-vif-plug-provider=/path/to/ovn-vif-foo` command line option to the configure script when building OVN. .. LINKS .. _Open vSwitch Integration Guide: https://docs.openvswitch.org/en/latest/topics/integration/ ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/000077500000000000000000000000001504532661100220045ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/images/000077500000000000000000000000001504532661100232515ustar00rootroot00000000000000ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/images/ovsdb-relay-1.png000066400000000000000000002047661504532661100263630ustar00rootroot00000000000000‰PNG  IHDRêÖøDõS ½IDATxÚìÖ1q!ÀŸ+®¡£¥Ç €D ØÀBè i3¿«b??ðO ï ï€¾€¾úè;è; ï€¾€¾ ï€¾€¾úè;è; ï€¾€¾úν÷œ³÷^kÍ9ǽ÷ÖZ­µ”’sN)ÅCïû>ÏóùÀó<ïû†bŒ)¥œs)¥ÖÚZë½1æœk­½÷9çÞkVúÎ/»ukQøX.ùZŽiNi¹oùZ˜s˜·òµåK[š•í>ß.<8vÿÏ}ß›ÖZ¥”‚1FJÉÃ?/À3Ƥ”ƘB)e­õÐwðO½÷”’µVAy¾AQJ9çJ)­µsÎ{cÌ9×Z[kcŒ9çÞûœsïýàgÜ{Ï9{ï9磵VkÍ9ǽ÷Î9­µRŠsN)E=ßB„ÖÚ”Rïý;µ£8¾¢`²{2,v0˜Õ`/‚Ánв¶žVW–,ö4ì&Ád3­ç½ta·?×ûίG…?G­ ïxǴ֜󪪒$!ï<Ï£”¶m;ϳ”rÛ¶û¾-À/¹ï{Û6)å<ÏmÛRJ=Ï#ï’$©ªŠs®µþ§—Aä;h­cEQø¾OQ•e9Ž£Rê8 ðçŽãPJãX–eEÄáû~QŒ1­µäû×c„MÓ„aH”Ҿ凜çyZ€sž§”²ï{J)q„aØ4â«6ÈwØ÷1–ç9q¤i: ò,Æ ðƘeY†aHÓ”8òŸ·g€ ¿Ê¿t„ò};ÜÜܤ»»»kÏ é* åû“¶X,...Ò ‡Ãö,P)˜®â°Q¾?EÓéôôô4Éáááׯ_Û3@aea’JÄ Eùþä¶2%999±N€RYXq˜¤B±rQ¾?¡_«ýýý$ççç³Ù¬@WqX‰˜¤r±¢Q¾oÞçÏŸ÷öö’¼zõªý T(&©h¬t”ï›ôéÓ§t¯_¿n?•‹é* åûf|üø1Ý›7oÚ/@EcºÊHùþØ>|øîíÛ·í Ò1]Ť|ßÀ¹û»wïÚƒ@äVŸÁgï»ÿ}» à+,åûÚç̬êÎ nÑT^Ê÷5ÎwßÛÛ[Õ[U¼d­¼¬È”ïkÙ«º¿¿¿Ú‘˜&Y‘Y©)ßWi:­c76:UjVpÊ÷ÕX,§§§IÎÏÏÛJ@Ef’ ÎÊNù¾INNNf³Y[)¨È¬ÔLRÙ)ßÿÖÍÍM’ÃÃÃïß¿·5€JÍ Î$ŸòýÏÝßß§[ës`¨àLW *ßÿÄ—/_Ò ‡Ã¶fPÙ™®BT¾ÿžÉdrppäîî®À£¨øLR!Z9*ßÃÙÙY’ËË˨4Iå¨|¨ëëë$/^¼˜Ïç Q%h…h’ŠRùþÿƒAºÑhÔàÑUˆ¦«4•ï¿27þ¥ r4]ª|ÿ©—/_&¹ººj°Q¥I*Påû»½½Mr||¼\.lTEi¥i’Ø·# ¡0Šã_PåI’Ó¥$ÌÊ¡,í¹&AÒÄ×Âr ƒš$ˆ›òä~»ûfw¶Ù•GO:?ç39ÇùþW×uô4 ÃŶm}ß×ueY†BÇq,Ë2 CÓ4€—išf†eYŽã!Â0̲¬®ë¾ï·mc€†a §®ëï¿ö}·m›ˆŠ¢``^×UJ™$‰ëºôàºn’$RÊu]ù@QDdÛö¾ïÈ÷oqQ|oÓ4åy.„  Ó4=ÏKÓ´,˶mÇq\–å8Žó<•Rü2PJçyDz,ã8¶m[–eš¦žç™¦IBˆ<ϧibæ ˆ(Žcäû—¦iˆH×õyžù®¤”¾ï_“=Š¢ªªÞöt€ÏÉ­ª*Š¢kÊû¾/¥d¸·yžu]'¢¦i>صcZ B ˆãSQ_Eð‚T ‚ ×Тbû“ Z*Þ ÅYø.Ùù©øgw´çûÃ9 Öªs×^J±Ö¾Õc‘ßžÕ‰ˆx¤‘ãÛñÖÚR ÷ñDšÕZ8çÆªó=¥ „°•™sæœ18¼÷­µµÖþ ""ZkµÖ¼÷8Œ19ç9çV‰ˆBRJzó]DpôÞ·&÷}_×…ãÿKû<Ï&"¢ûcïaÂ(ŽŸöùWHE0IŸMÔõ¨ÙL¢GUŠ H‚¦'}åM÷=»¿M¯îóýô|îÙݽÏã v\+s€;Æ€x\Y•¹Ä­ïý~_Òn·Kax6Ù÷gêt:½^¯éGÚŽîïßVGzŒ‹«$—؈õ}»ÝJ‡)ŒÕj¥¬×ëyÜAúA¸c\™ƒ=ÆõU’«l¬úîß»ÊÎçs à~¿/Ý×ëuü8‡ù÷Þ!Ÿ„áúªÌ…6P}_,’–Ëe¡õzÔÁ`Àk(†#ÝÁ^/se¸$ŠK¬$Ú(õýt:Iúûû{>Ÿ©tžQ ÌkA …q°;Þ•9ð€\b]e%¹Ö†¨ï£Ñ(ÈU/ßVæ= ©P‡¼2Ç~"á«kmùõýp8Hêv»©tóù¼ÞÄ”G • ਯw<9ü€\h%¹Ü^ßÛí¶¤ãñaªUU·Û-pà;öãì"àB+Éå¶äú¾ßï%Çã÷îNçñx$@Ž}‡?wð@®µ’\qˬïï÷»ÕjÕoü‹ï^UÝ=&4øªªxQOdqÅuÑ-°¾o6I“ɤø93~þÈ›™ÈðŠÆ³h€ \n%¹è–Vß_¯W£Ñt¹\ žï®Œ¿ªÀOVẽ/àr+ÉE×u·¨ú^_½Ïf³‚÷ªÖ»™˜ _L“ôÑPüNV®¸õ|9õýóù4›Í²¯Þ½4»ÞÍ”bø÷Ÿ½³ŠcK¸ð¯ë¾©uwwww÷-yî/î1X‚Çq®aÃÝÁá-Ä]à•.ži2Ý—sê¬<Þº=·Ïœ/Ý=÷Þº6}iòôtwëhuý «ª¿¸¬ÏêìÎ)îLÏo;‘Û›Ù‘ZwìDÍÁ¸Ê€ÈrŸÐ’½Gž!¶­þ…þ•¿z_Þ“0þþ1ضÿ /ˆ,ó‰­ôO¬I©;šÑžÓciM,êHute•öæUž*¬=íè«>ÓwöÊ¿oݾ)(Šb~-¹£ BPµ .Àw½Šà»\pæç?ÿ¹PT7nÄbël•öU™9õÌÈÙþ®ñFô®½+3»)*¾*è¨s—oÁš½'s»ý ÖwíN¨Îiжweaã ðù«Ó·gn ÕEQ̯ñ…R@5  PBiQЕKÐ(‚ïï~÷»^pFþ} *--æÔÍÛ7FÏ 4•´''×/ÝX´é¥«w¿å©ÀâÍG]{¢+üj%ÕK­ÏhŒÊjŽËm=aiO)èÈ(êʱ÷X\}e§l•®êÁ²ºáªÆÑº–±Æö‰V¸e¬ ÿˆÖ –ãeý6W_¡£ÇRÜ•[ЙimO=Ùš”ÝŸÑÖ‘\w<±æpdù#Î]þEqñï¥Gˆë‚¸"ˆË‡¸ Ø2R5q~xfö¶PNÅü\¨Ù( ¡º(ŠKÐzUÀw¹Íê7¾ñ µ›Ù±c‡0Î]™ê™l.íµ¤7„uî|ÑËc…ë9<#Êÿ…ÞE£=ÖªÓ%M£ “ín7ÐÐ\°´§f4F'ÔŽ(÷=ìðݽòÁ#ÂÕ>ÜÖÇs=“-xÄÒ‹¢˜_æÁGh–ƒ( ¸+7a5=¾ñ‹_Tx›ÕÀÀ@ݧ>õ)c_œ»Ž[Ò C¥ùmI1•~ Ö>¿CìÛc*³šc‹»sËûíõ#5èWS»a¤¶bÀ‰ ¸¦UádÛúü£Æ[SágmM¬t é»vóŠXQóËü¢&P¨ ¡º(Š›°}Íï¸ ÷*êüùór#ªôôt~5­k¢ÉÚvâˆÓó…jo]hé>ÜÎÎïHGG¶O´¡/•wÛxKy¿× ñ¨@hÉ>¼ Ïg޹v´§àÚHÅü2¿: 5!7vAquEQ W>1nb|Ç®Ñ8ooo…7iúõ¯- £Ñ³¸¥ŽõæVšWÞí;b«‚²›ã½V\Ö’uHã­pöZñxn\Uð!‡Ç~˳žÇ« Ämzïî|2î΋Š¢˜_æ•¡m좪(Šú"éÀ`Sâû;Þñíâ´zzÛÛÞæ–…À¦.MØ:3‹6j…äm]‰°ÜVv[Š"¤ñÆâí,÷õ±®ÔÞö€¢ ˜ˆ©Kã‚¢˜_æw! £>„º¢(JÞj›ß“’’0ô¯|å+BEEFFâè¾ýío‹{¨Ž±:¬‚¬Õ–„KmÇBË÷¶ yw¾‹Xž³Z&¥c¼^PóËüÎC(ÔJD¨+Š¢ÀH:`Ødøþ›ßüã *ê?øŽ.""B,½Î\~ÆÙtç0VDŽ« Á#žlb÷%ÇW‡àk…r^‚m[\=¹\Kžb~™ß—Šõꊢ(0’6¾ aÐÐôô´PN8´×¼æ57nÜK©®‰ÆäÚ#ÚU"¬>‘Ó’€g:S4žQƤ`j´iJ­;Æ'ã)æ—ù}1¡8P(T‰PTE€% ‰Mƒï¾¾¾ñßÿþw¡¢¼¼¼pt<ð€X2Õžv´o×%¶*ÐÕ[`䤽ùØ7G›2lYÕ_,TÅü2¿:õA•uEQ0I›ß¿üå/cÄ™™™BEaãk]nn®Xœ=¥­úlÛ–Õ‡­ÅMÔ‚\ˆ:³)6¨x‹œÁèŠØ R¨#Šùe~uê%‚*ꊢ(`0’$6¾755a¸+V¬*J>„[Ÿ³³³BWÝš¹YØ‘*kÿhcAGÛԼƢuÚŠuXðöÌ-¡‚(æ—ùÕA¨”ˆvW]UQFÒÆ&ÀwŒõñÇWxÍÝ—{o©¾sÉ{¡·M´²AÍîöɶäºP9§!¶mícµBQÌ/ó«Ãð\FyQ`I›ß?ýéOc¬………BEÝÿýú®¨óï‹c)w¾ßv¼Ä«¬ßÆâTÉe§lÇ\{åü¦7„åÒ4Šˆùe~uX•…"ÔEQ€a$`lt|—OμýíoŠê£ý(°¡¡Aè¡’Þù«N¶&±,UuNKâ~ËS˜èý–'«ú‹„¢˜_æwÑB‰ JP(BiQ$–ÏÏß÷îÝ‹Q>öØcBEMMMÉß…ÂÞݲû±ü0¿ß¦¼ë‡«b*䌗öæ ‹b~™_$G­uEQIß¿öµ¯i«²¨'›Í¦×f«ÙMQ² :3YËÇùérÞkO;„iE1¿Ì¯^Û¯¢V„©´2Ði@Ó´0ªäJSÀcãâ»\•åÕ¯~õÌÌŒPQ‡ÒåÞBRía€·õiG…¸ÜœÛš(  u´ZP¦óKë˜_yMµ¢0¾Ó4ñH 0–+MßCCC1¾?ýéOBQ­Y³èïï/îBö®L|ôûn(ë·³ —§Ó£$ô>Ó*(S‰ù¥õÊ/ª…‚Z1#¾÷NÞ6ˆiÚàøŒv@²AñýÏþ³6>%õûßÿ˜žž.«¶Ñù¹ïèµ²—³“êŽá4ð¶<~e|1¿´ÞùE• PP+jã;MßåÕm@²Añýo|#Æ700 u÷[­®®‹ÒÅkç|¬+ñ¡½Ùt\U0N†À¢M81ex1¿´¾ùE•ȽWÕÆwš&¾Œv@²ñ½´´T[ÛRU}àÀ1ö÷÷‹EÉÑû¨ ?6Ÿ4Qî‹S'†  /æ—Ö7¿¨ jEm|§iâ»¶'PÙpø.—Œ\µj•PWozÓ›pŒgÏž ¶Ý>P°Ÿõ®¾BÖž4“§„_Áº™ÙAXÌ/­{~Q%(ÔŠòøNÓÄwà±\>Òpøþãÿ#ËÈÈêê¯xŽñÆ‹¹OÚo“û2²óè¹>æÚÃu$/æ—Ö=¿¨ jEy|§iâ;ðy* ß±,ŽD[µw øïÿþoãìì좊ÎkKaáÑsmiOʼn‘Õ)(‹ù¥uÏ/ª…‚ZQßišø.÷ý*˜ „ïòÁ÷ÏþóBiá!±(E–ûàS¾„wÞég»¤¯'Fd™  ,æ—Ö=¿Z§(ï4M|‡Éòñwữ¯/Æôä“Oß_LòÁÙ†‘Z=×#µ81pzʈb~iòK|§iâ; y0ßÿøÇ?bLqqqÄ÷“\.ºêt žëêÁ2ynʈb~iòK|§iâ; y0ßßýîwcLÝÝÝâ%E|/ìÌdáÑs]Ü•C|7°˜_Z‡üßišøHFÞÌFÁ÷¡¡! hÅŠâåD|OmgáÑsÑM|7°˜_Z‡üßišø•y`³!ð=++ £ùùÏ.^NÄwlóÁ£ç:²Ü—ønl1¿´ù%¾Ó4ñ¨ŒÈ› ï;wîÄh¶nÝ*^NÄw¸ôT1;OšÆÉ ‚2¨˜_Z‡üßišøTFä͆À÷ßÿþ÷MRR’˜‡ˆïÑ•¬=i'ñÝðb~iòK|§iâ;P‘6ß?ô¡a4âåD|÷/Ü€ÿvôXÙ|4NyJß-æ—Ö!¿Äwš&¾•y`³ûñýÒ¥KÊÿÿÿÿ‹yˆøžÓ’€ÿ/óiŸhcÿ-gãÀi O â»±ÅüÒ:ä—øNÓÄwÀŒÔžÝŒï555óßo•øŽÏý¨ ?üŸ°2ïæ±¶àò4¦>¬Ô§Nü#ñÝðb~iòK|§iâ»Ü{ðìf|—«Ðÿýïóñ]#€c®=õÃÕìÂåfLúQ×­û‰ïÆóKë’_â;MßÌrŸS7㻇‡Æáéé)æ-â»F‡žØ´¸œöh,=äðкŸøn|1¿´^ù%¾Ó4ñÀŒÔžÝŒïÿøÇ?ñ×â»Føæ“¥=…½¸Œ‰ÆtkÝO|7¾˜_ZÇüßišø.Z<»ß¿öµ¯aåååb"¾Ã)õaòçÑþ¸®Ã‚Tø¢¦XÎ5&?!¾_Ì/­o~‰ï4M|0#õ€g7ãûÛÞö6ŒcllL,\Äw¸¸+'¨x þ•oþšÜÖDõšÆ´br1ŘhL7~B|7¾˜_Z÷üßišø`FêÏîÄ÷Ë—/c¯|å+ÅbE|—ß…Š­ ’/Àbd²!0©”«ËÁ˜bùMGâ»)ÄüÒºç—øNÓÄwØŒà¡Ý†ïÝÝÝÁG>ò±xßµk<'ü ×É—/ñ*èÌd}š×˜>L¢œML+&WþœønRé’_šù%¾Ó4ñØŒà¡Ý†ïv»#øþ÷¿/îZÄw¸q¤6£): h“|ñçnk{*«Ô\Æ”aâä b*1¡˜Vüœønjé’_šù%¾Ó4ñØŒà¡Ý†ï Á?ÿùO¡‡ˆïÚž ÙÍñÁ¶­òW°NYfSŒÁ×§£1A˜&¹¨ŒéÃ$j;ûßÍ.]òK3¿Äwš&¾›| ´Ûð= #X»v­ÐOÄwé¶ñܱ=hß!Ž(÷µ¶§µŒ5§óhL&S£M¦ ‡é“/Pß)æW/3¿Äwš&¾›| ´Ûð}Ë–-···Ð[ÄwÍE]ÙQþ^yßys}bÍago>«×½Æ`"0r^0A˜&L–ö…ñøÎü2¿Äwƒ›Þåsð©u;bÓŠ÷ë'MøõMž>ÄwÝlFðÐnÃ÷‡~# K&â»voOajóäŽÉuÇmݹͼžwï®Õ5Ù»ó’ëCñæÏ½\‡©ÑžŽ ¾ß™_æ—ø~/M·œ¾x<.®ï™Ö~ø‘} g×Ê ž‹û3ýÄá×ߺâmÄwÝlÆ{ „v¾ÿñÄ222Ä‹ø®ÙÖ}2¦2p¿å)­~¼­O‡•îG•²-EçÑΜ–Üa÷¶®ÔÞvL&Ó¡½ŒøN|g~™_âû½7]XÑ!Ï¥4k%ñÝø6ã½B» ßøÃ.ô˳Äw]\7T™×–Œú‘›xkƽ`ìhiK‘K/ÚtÃHMagf|uˆÑFùÞj‹Q`è¼¶L|%ñøÎü2¿ÄwšøN|_в@h·áû—¿üeŒ ¾¾^,BÄw\ÒW„Kw¡¥ûå%=ÍÁ¶mIuÇ=vù‚žˆM©=h÷˜ûNz[žÆ¥»ì–øò~ûÜ߉ïÌ/óK|7²›ûÏ;jû:F®êõÖõLuß\üS.Ú‡¯è5f<3ƒñÌß»F¯WwLü‡½³ŽŽ#WöðeffÆÐ2Cx™)ÌL¦0³!ÌdˆÃŒæ0ƒ1´L¡ËÌ7»¾ójN¿îɤcOü~:õÇ´FRKÊ(õ¹T*Eo¡½ú«w…ï±N`3s B×¾ÿä'?¹ÂÈóÂ÷ÈÉ_ßùj>*ß…?s2sç0L}„BC½Už/³ò¦‚ aZ˜¦È7isw^W™½çµb&Ö_Wø.|×úÕú¾Ç«¼ü‹ ƒF¥ï‡ Ê{©þ·zqÞÓ°ÙOëÔoþÈSÁº>ö _=Ó¢Ÿ‡Ž™Ìçý—¾ü›ç[wþÚ׿ESŸüÔ§©¾q[é%»±|Ó.ªßqwCÐ9qÐ>»ÎLž³$|ŸL˜²€FÚvîsàØÙ&pâ—U×»¦g „á0(†Æ¦oàL´09L‘ÿzEá»’Ö¯Ö¯ðýzÃ÷~FÙÄvë3pOÅ[8«àRòZæ²;)³:o¿=b_÷Öí?|¢åcÞvøné©çÛî;‰› 8eS§gúŠáý/|Q›™[ºÆðýø=øÏÿüÏ¿ð=Ö[öÄKF án]EÖÒ#3ñ7¹cXzQ‰¡3t‰ŽÑ=:IWé0ÝŽ²·êÿ}Jqœ´~}¢õ+|Oá„èÅ 3}f¶M8°Ë#èl#'Îp¶ms5Ǿ;/— {KÐ¿Ü Þß÷WñVw®;¹Ã÷ÙõÐJ†ÄwÃt¯Üzç½æ Ä笕ùV¿_±Ñé³…ï1J`3s B_=¾WÎ ßkœüåñÒ31³qºŽ°ìzsäÊҹˎÌbû›ÀÕÙ2Øã^°wü¼=c¸à Ó·&3§ÍPØ ú`ZCøÀ#™|EŠQ˜*T¤:Ð Ò,ó ^Äëx)¯¦t#tŸk?¾+ ßµ~…ïÂ÷§_ht‰1É][b=;uöig–îØ=ѾsÐórñ}å–=†ïÎxßÃ÷|·£´áñ½wòð(ø>&}ŽU,{å·¾b³³Ö ßã“'…ïÂw‰œg”´~kß…ï­:ô°S˜¾|‹éó–Á¶í¬ã›·—ÛçMÛË|øßGÇ÷y‹7fÑ+aÝá;î4Qð=dŸ¯ ß ßm‚Þ8ÈÄ© …ïÂ÷Ø&á»Dø®$|—ß…ïŽwq€ t·¯Ü)ÒŠ×þ`9¡{$ ñ1tH|"!ñ=dŸcï8ùXE_€y„8Âwá{l“ð]"|W¾K„ïÂwçÌí» üũ݂Àxó¹ÃÈÝ`ðƒ¯~|ÙçXàûáS¿´Š?ÓÊw;,¯¾ ßkI¾K„ïÂw‰DøÏ÷­Ú•FÐçú¢Ã–ùÊ/ßá§ÍöÒ ;¼å‰tN¦K‡Nþ¢úñ=LŸ£ã;¡â­äè´YáñÝE‡4*u¦åœ8ý7 /|¾Ç6 ß%Âw%á»Dø.|GˆÒè½Û螆ÍÀâ ÙY¸ÝEÍyŠœêÇ÷0}Ž‚ï¾ã³TÄ?<¾ã¦ï½¤ K¿½ZÖwá{u$á»Dø®$|—ß…ïÇO-ŒŒ7 ‘jáØM‚—(-XºÙ÷Uç^)ñ}àÈ´0hKƒÖ2öloþÚ‚ƒ–¿ýð+¡ûìÂbF>äŠÛ«Eûä˜EŸû\}%︻!ù„u÷ÞuŽï}ô©\õ*|¾Ç< ß%Âw%á»Dø.|wfub™ÏX¸rÒì\Èûw­ï3'q©¾·òmGüá_®pÂù~Ñò­æAE„ïÂwá»D"|¾K„ïÂw‰Dø.|¾K„ïJÂw‰ð]ø.¾ ß…ïÂw‰ð]ø.‘ß%á»ð]ø.‘úW¾K„ïÂw‰Dø.|¾K„ïJÂw‰ð]ø.¾ ß…ïRÿá»ð]"¾K$Âwá»ð=þE"|¾K$Âw‰Dø.|¾_'²iׯžÉ=RF¦Øã’͹<ŽÊ%-.|¾kýjý ß%á»ð]øw’17IøÂ—¾`ÉÓx¬S¿Nõ¼]ê_Iø®õ+|¾K$Âwá»ð]ê_ø®¤õ+¾ ß%Âwá»ð]ê_"|¾kýjý ß%á»ð]ø^öfiIiɱsUWÙÎÉ_žØ}lבW_²Ø©_ £þOœ?¾³rÇÉ_œ¸‚Î0œÛ+ÏT\²äÑׄi°âíòﺲ™)«Œ±\²eö¿¸ŸÉ¾×ʤõ«õ+|ÿ÷¿ÿ]VV–””Ô¤I“ËÃw‰Dø.|¾£Vûêÿ½~ÏzBªwc½ìuY®ÀÝ ïúIŸ4{¤i°nóÇšóÕS-ž²Ç-{77y¨‰kuþ\Ûç‚j5}Nú}Mîûä§>‰4z Ñ„ãɉ¨þ‹RÒ5xǽwlÞ³)丬œO ®.d˜0‡¯XîÆÅÖëÀÏ?¾tËo±SÆ0ÆÖ[Ã4ô–b?üÉÃÏ ²­¬äñçûê׿J]òÄ™¼UÖn[Kz[u¶²sïNÖáý§ö ßkGÒúÕú¾Ÿ9s&???55µU«VuëÖµNºtø.‘ß…ïÂ÷Ò7ŽÞÓøž÷EJ]úv±2-;¶°œâ#EÞºèfË8z[÷m‰ØÎ·¾û­ƒ/°*X¤º'v –AïÕ¿)Ë`áyËç]r\i³Ó"vƧ°û î±Ø¸iã\™¾ûsÓí7¡¡ù`ê?äœ ô6â(žo÷üñsǬÌâ 9–iÍ ß¯ë¤õ«õ+|Ǹ^ZZŠq=11ãú—¾ô¥àÖ«W”OKKë/ß%á»ð]øÞ{@ï÷”}ŸÎlRc=ZU¸Ug™X¶(³"o¹=3Ðjù”4f-6»ßTø²-KÙìf+ßlr$ `Vevî,§A3W/BwNÏšfº?¨þ-µïÑ>ÿ`þ®ª]c§ŽµÌ`§£m¦£V­$66BÚažd/›ZfÞþ­Î¼çŠ­Û¾–2ŒË¥ešýÒ©K؇&ÎÌ™rNöžØãh᪼C†=Ëdò}êß&¡[B7Ë¿…ð]ø®õ«õÿ:ÔŒëyyy×[¶l4®“¾üå/7mÚW™œœÜf.\¸p%¾ï‰ð]ø.|GEÙÛÙ"÷æãŠº2mg&7{D5z‹¡ÂÉDëÛ£Ù¨ºöëê-C˶iníРéB¼H]™ÂCSÿ=Szz[cÏ:h] ʦݛ¬ Þëªk£@"˜¿Á ·ÜxÇn»ä>ó¨Oý?øøƒæX~NZtxÁlF®'lÐÛx͕֩ÚÜwr¯Ž® ßµ~µ~ãßÿõ¯…1®·nÝãzAAÁÙ³g¯ÍÑU‰Dø.|¾Ož?ÉgÐrÒ¶kûÊ^Â{Ü^¾Í¹ÉZÎÌì–ã6ÐQfh8gHÃŒÇq1>çȳ*ã§÷½Î ZAõO]ß96ƒ LzæõKË^1‹—Û¿íîÛx©«ŽÍíÜúíë¬ FD_g:ôìà»Sÿ»ªvº2aæD°Gü |¯˜³d¶}µ|ë2¯úŸ¼`²"Ïßµ~µ~ã ßOŸ>ݸþ•¯|ãzrr2ÆõòòrŒëŠ<#‰‰ß…ïÂ÷~ƒúz•nD;ß<–-¶Ça‡zmZ(c‚{½;È϶~eÆv3_ù6»ñ²õ½nDúˆ úÇ옄ãô˜‹wá’3"Øä\&>¯œ'CÍ…˜LËœjßÒOÔ³WØ‹·¯ðF°‘g)Ìœ8ã( ú^aV=fêßyâ ß…ïZ¿Z¿5‹ïf\ÏÊʸ޸qãˆÆõúõëc\OOOǸ~îܹj )‘ß…ïÂ÷'_x2¸}l’µ6Ó:†“¨åÜrç-vÌmë¹}÷vÞ=e ZÁc^ìYï9¾›#ÓGZΡWú^7#kzPý;]´ó¡Ý-ÆÅÔ?aïˆAñ<Ÿíw' Kä1zÂòç”:;õÁÎDŸ,s—|>²^õÏλð]ø®õ«õ[ÍønÆõ‰'b\¯S§NDãz³fÍ0®/^¼ãú;ï¼£¸ï’šá»ð]øn6¤ˆF2Ntùv–=Shnçšc¾Š®@oyƒ¾ñ™hO ;}µÐ‚Aõ«¯˜;`÷Ðñ™(×€Wxµ·0œ•Žp4å:ƒ%¯0¹Ù#ï"ÌEDa§>ºú>'.7Ü‹½?á»ð]ëWë·:ñýŸÿüçÑ£G1®'$$`\ÿâ¿ѸަMŒë………×ãåÚ&‰Dø.|¾;Î?¶¯Ü5%G^;b9áÐî>n €ÚnãÎ ¾£u˜Ó¬[ÕD´ð…pba%‚¾³l—ûB\S&¢7ªï½tÆ4«úæ¼{½žè`}Ð@uB^ð9ºú>'îÛgZ=¼Œ†W ¸ó ß…ïZ¿Z¿1ÅwŒë[·nŸޢE‹ˆÆõ¯~õ«×SRR0®WTTëñ‚ï‰ð]ø.|w*»—ïÖ@öЃÛßÜ]b{Íf s>£Hî¦\¯¯­ mMñj!;k–ï.C{]Pý§ÎJõ–ÄÿÕ…¤ãìNàùš%ËŸó ðUÇ1×ô}4õbNwÕ‹ïÊÉÁã»øtÂwá»Ö¯Öï5Ç÷ÌÌLŒë5Šh\oРÆõŒŒ ŒëçÏŸ¯¾½ð]"|¾ ß''ñ_|ŹÒ+¾¯‘ca¦ŸV­r.°X›¬W¨¥ˆÚ7¨«ðUµLüq±ºö;öêèµÃq÷¡=Oæ¢I €£Ä&–³éNîk¤€ÛÊ2."4[ÝQ£¼wª£¤½®®.~óÜ¥s\‡SF¦Xæà±ƒ¢«ÿ¨sâßïÕ¿먋 wøb¡þùIðÃàç!Dޝûõ«õ«õѸ޼ysŒë¹¹¹×ß}÷ÝûÑ ß%Âwá»ð=û@ÿËï}½äŠõĒ͹^Wb, ™‚66gÕC¯?4!b´»–ßVn_§)§ü¬ ,¼—¼`´2­w.ñ­×ù•>_k\ä ø"!«îük¹“ÅõMsbb¸¾q¦Á†QÿÑç•ï^M1^Á‹Ü ð¸‘úç'ÁƒŸ‡9¾Rìׯ֯֯u¦mÛ¶×‹ŠŠÌ¸/Iø.¾ ߅rø_>ÿäš«QÕ² Þ”2"9¢…ŒÈ>‹—ìsf«ó%®n!z´×±Õ¬h.=òÔØè¼êßLhhÓ!ã‡8 mèm˜Aí¬Üa‡ä,¹ê¾ÀÌ€¯¯0jcñmå;§ØðsbB(kF.qyº.Xœ¾«~ü0øy‘ã9E_¿Z¿Z¿µP‡ ß%Âwá»ðýÈ›;ø_~ÁÞñW©-0AËyÊÂ)œC¿šò»2Aï²Í-ë£ÀN†~%3hÓ"¦»ó–Ï3{UtS•™Ž£lF$á…{XPÉ#Ò†ó.ÞÙU‘A!:ŸŒ†mqnm$çšËÁÿaç 8"Žá0ü è; J]A® )ÜD…]A¨¬‡)ˆ‰Ä¶=¯à·÷Ýïåæ?¿˜ì0“­ÝMžíòË¿‚%0ö°"×,ó[ÆüZßE¬ïÖ÷Çýþñ–ŸÏž}ýÿ.‚òÃYì‘*–*çW̯õ]Äún}ïsÜñþˆ»~r¹îÚ“ fÀ#U/e~¥_뻈õÝúÞç¸_^Ÿ×Â2×ýáÍž›O°fÀ#©ºe~¥_뻈õÝúÞó¸oŸ®¸ñ!.ÂÈ›OâCÈNÀ©)ó+…üZßE¬ïÖ÷~Çfó)—þÆéÊùãÌ-8&=À˜!µ#õ3¿b~­ïý#Öwë»õí_osõ¯†¥¸8vއÎÑcl”2¿ß˜ß1ë{…ˆXß/ëû_?# 'wS7â8pÜzëzWæÌï';wÁÜÆ­qü~©~¤23¦ £™}ÍNbP͵˜Á2È’…f†È8.„A÷™«ŽÇ £ñÿ›·Ãî9ûîyF#-ñu°ñøN|K²%; ÎF–CŒÆý½Ôb5:Ûqµ>³ÇýËþ=pññø.ÞÉÞì<8eþôx33r¿.5W-ÎöZMÏìe`ÿ²‰ï@|'¾Ëå¿VZ‡J³ƒ¡Â{Ì?í`Xî¯O¹9ÔÖlÕhµ;³—ýËþ%¾tñøž_(°Ÿ-¡ŠD:ÆàÜë+‘Ž«•Ùžª¹jqfû—ýK|@|'¾Ë½w­)CvZ䨾±¤Ú™ {w©}jb¶›j«š›ÙOÀþeÿß߉ïYKëÓ Áœ_òqüØmäSq{ëómj™—í Z©†fö+°Ù¿ÄwÄwâ{ÖМ»Èù“æGv5ôç{&- ×ݼԠ†þ¼Í–©}jbû—ýË @|'¾g¥#-C¥[&ÊÏݱ Ñ•0³v÷,µCMQk6Û¤–©q4ì_ö/3ñøžµþÏe÷x׿ãŽõ¾ß8Pè²íìØc©ý…jG¶/ùöïÔ¦kÿ¬eö/û÷ ÏPÄwâû¦Ô¥á¦ÁâÍW‰Š]‡ á*Ï”u;gKWÙUüÍF4 ¥VB€ýËþe† ¾ßwåï´s¬#Ïöíæø9iú¤:p¦'Þ40ï¥Âª¼*²J½Yö<Û7ŽÑvµ#°Ù¿ÌPÄwâûsM®Å­)C…çˆFÑæÊ³wa°Ä6Ö]‰0¶_g©€*£Š©’n­p¥÷¨-e˜ZKdö/û—ø€øN|7¯FüíáªëW[U™çH[¤Ö7mñ™ÇR¹T´²ÿ†ªë×᪑ÅÀÆÍk€ýËþ%¾ ¾ßß”¥õߤqóÉÓÙu¬÷=Z¡¡?¿3Úèš0…—†²£Ž¥R¸&M]ÑFG%R¡¶ÖMeT1—×g3û—ýK|@|'¾¿U·ïÝKGL‰¦RwöCZÿYg-_VúŽ·„*Ì©¶¾Yw28Ã^§©“Õ)ëÄuú*Âã•Q¹T´±ôÈ{·2û—ýËL@|'¾o¿;÷nëU½ð¼Wƒ­¾ïÜY˽BçOõÁ¼Îhƒ}¼'0ã^ÜëÃ^§ Ñéè¤tj:Á'Å /êƒç̉æð‚O%º{ÿv`ÿ²™)ˆï”{·¹~ãÊøjÔ7ÙÛ6\YæþUƒð‰ëœõ+=a­:púâ`IûH)ipM˜úç¼#ËáÝ0àu:’L‡§ƒÔ¡ê€uØO;#l[¸Ò7iœXª€ýËþe¦ ¾Sî=çÞý»Ë×gõù9K²¥y¨ä}ÇõT5 Ëg¬ÆôH}D¬®/çÂ`qs¨Ü0\Õ©ÕÛs{âMƤÁ’j·u;'Œž)‹Úœõ ÌûC‹ý‘åPl%’Lǵô/úOýOý‘¾@_¦/Ö·ØÆºõíÆd«~”~ ~¬~¸~…~‘~~©~µàÙG¨góUé C%:)šNðîý;€ýËþe¦ ¾Sî}éÁÃzPÃòúÌØ¥ÈМË9ÖÑ5R{¾?¿ÌýÛó皯;¾ÎX>×Áèt`:<¤ui}F‡­ƒÏ¼‡^[[˼!€.']TìßíØ¿ÌÄwâ;ïǽúÏêÜÕñøò@hÞÓ?c÷O™Üã]öÔï¦DSO´¡#Rm•7 5sk§ô¸e}ª¬ÐñC®õëÓæÏŽ÷~¨¥Ñ3Ýô?K]‡ôú²Æ`®¾Eߨo×1'šì£mîñnýpýŠáy~~éÕ¿W·ÿ£iŠYêþ;ï¼C‚Ç›ÊtQéÒbÿ2Âl?â;åÆA [$xp9™€øÎ­D.p!`{ß)7^—˜)ˆïÜjAü˜)ØûÄw΄0pÙ€™€øN¹A¸`ÀL@|çV ¸TÀLÀÞ'¾s¾ –‹ÌÄwÊ ÂÀåf â;·ZÑÀ…f â;·Î5pI€™€øN¹A\ÀL@|eœ/mà23ñrD7p€™€øÎ­8Ðz0S°÷‰ïœ/ˆq é`¦ ¾Sn€0G»f â;·Zé@£ÁL@|çÖÃù‚`Z f â;åˆw4`¦ ¾s«!´ÌÄwn=œ/ˆz ¡`¦ ¾Sn€ÀG+f âûkà|AìM3ñr„?Ú0Sß¹Õ‚f ö>ñóA´ ÌÄwÊ iÀL@|çV B!h˜)ˆïÜz8_ AƒÀL@|§Ü‘ÖÌÄ÷×Áù‚˜šf â;å‹´`¦ ¾s«‘4Ìì}â;ç ‚#h˜)ˆï” >R|€™€øþú¸Õ‚ Êf â;划`¦ ¾s«òðáÙíuçÞ­«¯Î]/ Ï{úgìþ)“{¼Û>ÚfN4õD:"Õ†PyÓ`Qc0·&pªÒ{´Ôu¨ÐñCŽõëÓæÏŽ÷~¨¥Ñ8~Ðé jü§‚9 [Ceíáªîh½1~Ñ–2¸Æ:}“½ÁiëМ+µ2¼xmjýÆå{÷ïf¶—м ³ûÿ``¦ ¾ßü[Êî>ظymi}fìRD¹Ù9ÖÑ5R{¾?¿ÌýÛËçGÿxoÇ×9Ë—žÃ ºGêœc:ÈÑKaðÆÍ«÷Ü{K >›Ý‰ï ¾ ¾Sn`ÇܽgùúldÁoI¶´ •TùŽçÙ¾}vt>aü(Ïþ]™çH]_Î…ÁâæP¹a¸ª=RÛmì‰7“­–T»m¬Û9aôLYüÓŽà¬g`ÞZì,‡b+‘d:®[ÑêÎôþ‡gÊêš0ÚÇz,£¦¤áxsWô|ûHÝïáê–PÅÅÁ’šÀÙR÷o9¶oôâý³P¯ëë}½üom‹-õ§7<¼Ï=Ûø€øþº¥ÀõW&V£¾Ic[¸²ÌýëS_Þ¶~Uì:T8­Ü¬ ­<íš0õÏyG–éÕäŽ/E…~Å}cÒЩ»0XR8Sâ:¤Ã>ÖûþÏH¯Ö·‡«üS¦‰Õ˜ŠÀ=Ä÷]ñQ ^\¿­·”„|æDs}ðÜYËçÚBçOõÁ¼Îhƒ}¼'0ã^T>ÞÓ+¼4Ô7ëÖ ùí‘ÚÚ¾sùŽ?k•¢¾ïœ)~14ïY¸6uëî î9 ¾ ¾ß –Ž¥GL‰¦R÷¡'ÅÖ/+}ÇõvsªM7™N(ïîû•¸ ̸LIƒÞêSé=®"<^™rÏaK²U¯Íë EÜs@|@|§ÜÀÛµ¼>ë›46s¶FÒc½9nèÏïŠ6º&MzY:gY*…{Ò¤·×7ö»~9aüÏûéûóüS&}*€{ˆïˆï”ûô|˜‘Å@G¸JÖÜš>õ¹Ò¶H­oÚþâq–å²ý®)u~äS°íá*}´÷ú«Üs@|@|§ÜÀ«˜ZKØR=\ekÐÔÓ`ô NÛXwt%ò:)–] ÛÆºôP•ô±w×´èÝ5Üsžmqqñìÿ»yófæzøðáúúú72ϳ±±ñçŸf^Œ¾8N¿á£%¾ ¾ß+§£íy¶o6åIÓ'zâŠר'3¾ ËRaUÞšÀ™S¦O6ËžkûZ¸ò÷%î9Oôì l•Õ¶Ço®fš‘Dc&¢$! * ‰‰’%„‚b >yO2Ïc™J¡E( ”ŽtžhíhJi©ˆ¥-ƒ"‘ù½÷‹ë±ý<_=÷H±œ¶ÿVH»¿õM{ŸßY]kí¬¬,{¶K—.…xJii)þ}ûöý3‡úúú1cÆàcz饗fΜéçxà~Þ¼y½zõ27~5jÔ… ‚Üp7ÿ7q1b>±±±Â÷/I’„ïÂwI:ÝRJs‡´tŒ+ßI£táuçfפф~³§Û&‹rºµ¬ãë+|Ÿ:uªAy¸÷«_¿~·oßvn×®]ã €ß :¯««k‡²‡‡ †Op|ÿþûïÍgÿþýÂwI’„ï*á»$]»u9»þغG)t4.Ú@жHúéE1Å( ¶uYŸ17çlÂãõ’¾Ÿ?þ‹/¾0ÿvñ{ïÞ½Í!22²¹¹¹±±qâĉ6²víZç9räHœ;wî™3gZZZ8j#ÄÎqðkýúõ ‚ïwîÜIIIá{‚ð]’$á{0 ß%éL[ElÉå¥{Ìñª}äd‡Âʨ1`QX·Lq¥dƇÿÿ9<¸|ùrpŸ«W¯¶¶¶†âóØø¾jÕ*—åß7mÚdGÓÒÒ¼Iðh4hTTT˜Ûüùó½§Ï˜1ÃÆ}™6î”öñýúõë}úôqG…ïíK’$á»ð]’JÎgoÌœïˆpoÑÚœ†Ôp¦XYvC û^¹%có×¢¦ô°ú?‡hôàÁƒwìØQXX8aƒfBÚ¤¬¸úNGää”{sÇÉ-!ïªOÝ–»8¿)CàÛ,ÿ\FDÎÛú.ßñ­iž*¾Ã¬ù$eeev‘cÇŽñ+iñöëÎ; ħü‚,€šOˆ¥«¡à;ùúÞÌø¨¨¨¢¢¢Xª úüóÏ-Áݹ¡¥K—œ8qbìØ±6òæ›oÞ¿Oþ%rÏùú<¶ð]’¤P%|×tKRnC¢Ý²”'ªv»«¯úzIÒ‡,ô’¤iEM'Ÿ"¾ƒ°ã··ý"­]¼½ÒG¹:ÿ}ž ¾Sðê"èäêx Oq¶C¹û‚Š‹‹½a°¬z7þÕW_Ù“[Ïá»$I!Iø®é–$öÞ7v§}¸êS»½•ýP´çÔ[ñ¼†Ä§ƒï–ãî“åˆÓyÝ~% ï¯p%ÔMÌÛ‚û¾»Î0NtÚEÈ'Ϥâ7¹í,»fΜ9æŠÏ“Åw÷„111‡âããí•¥rn»a`ƒ*wògpóË›^ÿû, ß%I¾kº%)óL<è¶:mV~S¦X¶gÚáŠÝFð —«;¿ó̹sç¶s²ñ¶¶6×{q×®]^Ÿ;wîØøÊ•+Cñy²øN^»áõ!C‘vow± Tjj-v°=2]ëI7èÏ Rî»$IÂwá{ $©æâ7ÆmY ɢ؞lJ#ø,Múˆº:ß -;¤¦‹ ²ªÐÒ|èÃèrgdd„èÓ.¾òÉ'œEŠ|¨øîëJIŒŸ$¤ç£ ._¾ÜFøfb#äóq·ÁÜÜ\€ÞmDø.IRH¾kº%éæíëË’§mì¥*~•E­çðöäl>‰ï&¶M¥öÔßÑÅe“ƒ¼ì²4nÜ8xÚÛx1DŸ'¸mzðàWv7å €Ñ¶Û3ÕyÒDÒÆQ¿~ýxGwV}}½ð]’¤¿ Ủ[’²êk» W‰\ef» Vð‘àƒÑ™¥«FÉN p@J‰EµDïE²kB÷ÉÉɱÁ+W®¸³FŽä§L™Â!€»Ý£ìÍDMjÀ§NêMÁwR°p»èO_;ßÝ.N~¹Î6\_ø.I’ð]Ó-u±mþÊÔO`µœÆ4a«ÌŒ‰U©3þÏÃÎÁwx×:¦§§§ƒ¡€;m¿ó7hîNÊ88ËÎGÄ­C÷ù[uýúu’ah’“ŸŸïÜý"OÿGŠhiVC'Êm;áÙ„ï’$ ß…ïÝJRqS†í«*fõš,"g‘õ‘ì<|Q’ð]’$Ủ[R£÷ÄšƒV¯É’jãø`­ˆ¾‡‘„ï’$ ß5Ý’Y° JËUæŒì–Ûx’Fdþ2á{Iø.I’ð]Ó-I–ø^Þ\"`õ𬢹„¿ûÿÛuÚ´iÿÞU¾K’$|×tK’µ{/:Ÿ+`õš¬øû|ûlèÿœ°“ð]’$Ủ[¾§ÕÅ X½&K?s\ø¦¾K’$|×tKÂ÷¸òV¯ÉŽTD ßÃTÂwI’„ïšnIøÎ6=V¯É" VßÃTÂwI’„ïšnIøŽåK³šÉø0𑾇¯„ï’$ ß5Ý’ð=êÔa«™ŒCÁwvx]ÙžV­ZSWWçßü•}aÛ=e÷îÝÅÅÅ?ÿüsð;&&&š?Û¯÷dOVœ.\8|øð—~?Ìš5‹}d…ï’$ ß{útKÂ÷Õi³ø7ël²ÈUÆÇÀ>=ß ô êÕ«W~~¾÷”?ü0ø)qqqæé×ýû÷{÷îmn#GŽ ò`7nÜ=z´yúõÙgŸÝ¹sGø.I’ð½çN·$|?^µwæ/«m«¿ödãÀÇÀ>= ßßü£úõëÇ Qp?¾x$‚â …àSRR¼nW®\i×­¡¡¡OŸ>æCÐ}Ê”)[ÓôéÓݹ3f̾K’$|ï¹Ó- ßá¶Ý…«øaGþÒo[ÊE±=ÓXúyKùðaàמƒïýû÷÷"¼½víZ{‘aÆà;Qy® ©8Á#ëï¿ÿ¾9˜"""‚ìD‹ÆÓÚÚ ÐÛÑ„„á»$IÂ÷ž;Ý’ðÝ|D΢²ŠÅ²=ÍXô­9‹»‡!¾ÿôÓO> ž,~ñâÅK—.ußý$MÞKp|75Êüýõ×€C×®]³C‹-²šú¯––fn$Ï´{‹#GŽ˜÷¾‡®ºä1ah2™ð½C·¾KÂwG𛲾`ÓÍž¯Úc5oSÖçŽÝÃß׬YU“äýã?Nš4ÉBÎ@3<]VVàL5'rŽÚ}ã?þ˜¸uÇñRQ—è ¾O›6íÏð}Û¶mv¨©©iæÌ™ö³¿•Ô;túôiñ‹—µ×äËSÄ÷C‡577 ßeOÓ„ïÂwá»$|wOåbRíAqmO0šåvì&øn€Û·o_²Àý夵µµÎóèÑ£âI"ï ¾¿÷Þ{8ð Á“gLׯ_ÇóÏ.H¬Ý’ìù¹°°ÐEâ½>üyÁÆÉ§ÿÆ‘¦—_~™$Ÿ-[¶ÐK'üñýo–…‰ÉdÂ÷'v{á»$|Ç–í°ñ¨ÂÕÄe¸Ý8èÎÛZ³èŒ„¾›ÆO(š@õܹsm„jNs»zõ*$m°ž››KÌ›üPÒÜL|ú±s߉.Ûu¨õ—®VxDmëòåË]ÁkFFFÀÕjjjìPdd¤a:l•©ÞŒ ‚Ùæ6{öìðÇ÷¡C‡>ÿüó߬Þyç $''óeFøÞI&¾ ß…ï’ðK?s|]ú\­Hù„ê¯EºÝÏXV—%f¡YnFÂ߉OûcØtz Hn9wîœ×móæÍ®iLp|7èœñG¦Ißxã ¾$„Þ8’†ñþ¹/dðÛyA6RPPàÜøbƒ<WÙ¶©²²’®8|ðÁ+¯¼bãN¯¾úêÔ©S÷ìÙc9B£„ï2á»ð]ø. ß­–qoÑ:s ™ ž¬KiÝ!1–Ø*•Ãßoݺå'n±vûÕrâÇŽp:¬vúâÅ‹;Ò÷µÛ÷½—G§~öžrïÞ=‹µ3Æ ’jbÎ\Ð fffÚ`lllWÁ÷€Æ8TÖò§ƒ·ÞzëÙgŸÅÇé…^ ÖvÅŠyyyLˆð]&¾?ñÛ ß%ịÑî_•6Óܶå.N­‹þv]cùXD[M–•ŵñ°Åw—tî´lÙ2‡ïä·ØØñÔ|¬÷b(Ñ÷éÁÓ€&i÷= ŠÏ}'æÂ… Dúù:áoýN&‰ RØšðHÇw_nß¾mž\Ä×­[×µðÝ/6¬å ì_KýÀ‹/¾ˆ¿Ó?ÿùOjøË éI$; ßeÂ÷')á»ð]¾cÍ%G*£ÖœœmÎ[²&ׯ …»–±d,œ­ KÉ‚²¬Œ‡9¾“¸ßíF4[´£þ.tªyìÒÕM›6Ùõ'Nœß._¾ìoOÐýAEõ­C^¡sNÇÎÉɱ$úá„-¾û÷¢ŠŽŽæ Ì믿ιcñ«ð]&|¾ ß%á»ÛÓçØ·1ë3>³Sè3_¹Gý%ÃÜX –ÉšBb,‹èvæ |Áƒà»+ôtøëD›v;4yòäÇÆw.¦Ûc„ˆïˆ¯V“êŠk]'œ~>ù;¸ó0ög×iÞ¯!C†Ø‰wïÞíŠ}ßé陚šºpáBñësÏ=gůìPÛ¡âWá»Lø.|¾KÂw³šÖ*2.6fþg™í*X‘\{¨ª¥B¬>Ær°(,[&–Œ…cùÌ¡{à»k³H×—·ªª*;„GGÒ»ÆBÄwGü ¹PÖiOB³H¿¿«‘¥½½Pëi#ìáê÷ws°æ’ÝcÛ¦PŠ_Ïž=+|— ßGÂwá»$|wvò̱݅«'þëQ"õ~ýÍæì†¡óÓ5–€…`9l]X –‰ÅrÝ ß]#bÕ¤xÝ"""GùùùÁ÷#F„Þ÷íß¿ßîËVS6B“ƒH'²öÍûöí®ú“‹Û)®½½ÓÍ›7ÝF°$Ðw¿]W[ZZ(~ýôÓO)~}æ™güů+W®¤ø•¯IÂw™ð]ø.|—„ï™›Aµ ÆÛŽ­±¥Û2ê¾í¼x¼bí•™õ‰±eÛ™|o¸¥qÙMÝßI›q¸ìú™ÐˆÝ:ïà¶MädÛõýgr=ÊÎÎŽŠŠâwÛ©º?øÛ_:twí)Ý ­'ÝuvîÜI¸ô¿qãFVV–}pÍvº¾û‹_ùöEñë»ï¾ûgů‡¦øUø.¾ ß…ï’ðý/[Fý‰=§Ö.IúÐáãÒävä- óÏeˆ°ÿ+ü.ûxÕ>2d–&OwÓΰ,‡sëÞøÎ®L.ÿd'2 ‹»_KJJ:ˆïÖ§•••…Ø÷gƒ³ÍyΜ9šo_äÀ˜˜î'L˜ä¡éßíñÝ_üºwï^Š__{í5ñ+{{QüÊ77á»Lø.|¾KÂ÷¿`¥N%ÖÄ‚¶ ¿3r9ØÝ3©æ µ—=¶•7“VS¼aõÉOÝôZ3:¸'Öd ̳«ã;ÕvñÆáßM”oºM‘œ r/ Omw›@ùµfÍ·ÃhÐû©Ÿ?~[[[@óJ2|‚<ýXì „™Ý µ›$i‡ñ€mMñ·Æ‘/þAñë—_~ɺPíê/~åů¸ ßeÂwá»ð]¾‡j¹' ½oÏ[â É[ó“yJ#²Î&ý¥«)£ý`Ùö™Ÿ{griÒG„ÞUÅ4ezÃß;Q4x!ƒeÇŽPï?ü@TžÁ®.k'Ÿžž¾k×.þ%/ÜÆ…ïN.]ŠâWðþâWBõ¿¶¾Ë„ïÂwá»$|ÕjÚª2Ï&‚ì®}¡³ ™ó ÕÓÊ<­¸Xjþ2¦‚ aZ˜¦(`Ò¶dy¨"2§!•‰u§ß{¬„ïþâWâ)~åO7ÞâWá»Lø.|¾KÂ÷ÇSËýXãr?<¶2u&éò„™SOÇÏë9¼ÎËòʼ8¯Ï$øg†Ü˜}ßlJ?s¼òbYëß%á{@OŠ_iVCñ«ð]&|¾ ß%á{G]?³’}MÒ6mRŸøW³.NœJÀ>ºh=š9iß|_PÝZÙÕIWàEx^ŠWãyÍ€g*˜¦…ÉaŠ·G¾KÂwõ}— ß…ïúoZ¾‡G:7õô‘ß‚ÐKu.´eÉ3Ø:t{îWÐm\ùÎÕûÓëHþ¦¦3¬ Ly$ŒÇã!yT˜ÇæáÛ})^–WæÅy}&¡žPø. ße2á»ð]ø. ߟ°‘(’Ó˜jQj¾éfãTû9xsÖt²uÑáŠÝñ•{9ýDõ¤Ú8Ș݋è¨HZ9eµùM™§¾Ë¡-zÉ…SÐ6÷ªj­¬m«Æø_ä¸áÌ)œÈé\„KqA.ËŹ7âvÜ”[óÁŸWàEx^ŠÓyÁÎ̇¾KÂw™Lø.|¾KÂ÷ÎN¹¡ß9M‡ÊC廢‹7/¾!cþò”y‘01†GâÁx<’Gåyl> æPø. ße2á»ð]ø. ßÃÀjZ«J.&§:–¶-d­°ÿëþ’-1ÅI_¡ñ|dÁ rT¶å.Þš³ Jiê².}. Ô©¸—$}Dhã~eC8à†3§p"§s.Ź,ç܈ÛqSnÍðÝc>…ïÿÇn‚V …q~;Üz:_ú0Ø‹{vÍê,댵õ²5{°-/Ú“˜ 61Xe°0wáWÆóç_N=ß%|Çw|7|¾¾ã»„ï7ßÍð]ønø~z¾ã;¾¾ ß ßñ]øŽïøn†ïÂwÃ÷ó“ðßñÝð]ønøŽïÂw|Çw3|¾¾ŸŸ„ïøŽï†ïÂwÃw|¾ã;¾›á»ðÝð]Âw|Çwû;|—ðý8Žyž—e¹åx]×}ßñ߯S÷òøüÔ¼¿½þÊûøŽïønø.áû8ŽeY^.—ø\J©išmÛ¾ßÔuçy×uÃ0dYmÛâ;¾ëºìÿ¿ˆx¸¿;ÿq|Çw|7|—ð½ïûøi)¥iš¾ÎŠ¢ˆˆªªâƒ½³ŽãØÖðcf† SaNJ—|ýâøE7³“§̶$Ç2Û²n,9Kfff]Éb‹É’™™™™n½¿ü']S3«ÕZò®6Ñê”ËÓ==¥ùæìéÓá»Eø.|¾ ß…ïá»T*|?yò$Œî„õ‚‚‚+W®ÀfôèÑœNË–-áQcÅwJëÖ­ËÊÊ„ïN¾K÷m^¹­zñɽ9÷¸gá»ð]ø.¾K¥Â÷ððpŽ|×®]ÖüÔÔTæ§¥¥Ùð=..N[WýY„ï7N—ïÙ¸â‘Â{Õá¥cE×N–Þ“®./Þ½ay=Ç&|¾ ß%Âw©Tø~ß}÷aØAAA¶|l`匢¢¢¬øþØcݺuKøîŸ"|O[˜ðÒSX)J³‡þ;5¶ï­³•,Ðçóçžyô¥çŸ8µ/×Öpäðž,ºr¼[Nñÿ–-^¾y¦bøÀÎø?{CÏ3'÷d_·Eóq‰¬™ ¦Ç˜®86ìpýýùª&´@Âwá¬æ+¾/Í[Ò9ôë°ÁaLN_6 É!#‡xØ\*|¿ví‡=eÊg)ÜiPôÑGYñ=88X#ýS„ïýÃ?ûWÒâW/^=QŠ ó¦Ž`¸ÙÚðö¹Êû×BþÛ¯ÿÉesãX Igos¦|[ß÷Þ]ƒ\Ž->:¬ á»ð]8«ùJ„ï#GÇà!ÿ§ù'&CöFò©gŸò°¹Tø¾sçN;33ÓYÚ¼ysZñi„ï~(Â÷œc¸F¯þ|SÅηT-ìÒž™0¢ÓqÅp¹µmIöæ/šùÁwcqG)|ÙgLn¬æw‹ï™ËRÙ&ù¢ÌIpÅ©.še,ñÇve ßëá»ð]"¾K…rØ>c+ºyó&‹/Rø.|÷s…ù~/X p3¼_¬ù۾Ƶ;±'9_}ÖŽÉ3òLµÐnAÈùÛ¿ù+é ¾·z%Ÿ¦ZD触­çøŽ1Ôïûï³nf-ȘÀÞÏúNø^‡ß…ï‰ð]*|§Ü¾}›Ãމ‰±­_¿žEÑÑÑÂwởëþ-i\  ÉmE€c—‘,\5‘ÉY“¢X€pGNÏÎ0‡øÎ&6çuæcï)’p©‡9ߪØÞêÄw3¶!ý¾d©Õ£æãÞZ:'VøîS¾ ß%Â÷ªÝ•™•™ë®m`?lÈ_—W¾½¬Îj›Žnôß7ZŸ[“³ñð†z ÓɩήÙ_]gÍŠåžtX½wMÙöÒúÝ™5{ª0—:«¡NÑæ"Þá»ç€a7kÖ̶!uìØ±œQQQ‘ð]øîçŠÍ¦\ k—ØŠv®[Ê¢I©ƒi ‡ÉÖo¿Â yiãXaMáL¾Ú–îô±1WÁ“Zëøn¬ì ÿƼKÂwá»ð]"|‡ 葇Ìîg^xfòÂI¦Â¯^ùåcO=öÚ[ÿëløN ŠÚ¼ß†ÉåËZ½ÑŠÇ;|ÔÁ‰Å1©1-Zµøë¿ùkhËß´ümbr\â{FY:jšþëŸ/[½ÔÃy›3=˜¶˜ ¦‰o[µiK¦r0À{ß±|ºµBdì0Ì1èó |“`´¨öÈcx~O YU™ïvxçßÿóßÑ–Sþ6é·Ö& ²  F»ö@Íç]?ûž57 ßëwfSHHÈ7˜YSSÃ`ð@v$…ïÂw?שc‡r.-´÷èaÝ™9àkæœ?\€$ýãÜ,µâ;œÔÝà;¢Ðx‚ïØ&ËÒåó…ïÂwá¬æÛh"|¯ÜUÑüUìês!!ÝCXçƒà÷™³ª<ÃÚlÍüo†öArEár—ýÜ÷à}%[‹Ùå¯z}é¬nvâ;a×Yy̬1uÎ+:%Úå`lÀÝ#¢‡ËjÃ㇛:ݿ醜ö"›¥Àwï £u9‹Žw\pëL]<…™ìVø^?Á©L¯¿þ:dÇFÕçž{Î$+++…ïÂwÿ×¹SFXÜ­Z¹z†Í[†öxšÃ¯Ÿ*£çLâÈp'¾ýÝà;B˃୚½|Œß©†­Ð\ø.|Îj¾&Â÷®}º~ëÝ>‡“ ¬¿sÓçU™ Ë4êÌ^9‹É¾Ã¾a+dÃ,ä+¯ý|æòpV+mê°Ù$eZ²!à‰ó&€}&Å“ÝøNùäëOÒJÒòÖæEÆE2fìê}îœa€Å¬ 9BRâçø¢`‚Ì\Y´Â˜çMµ…Ù PóÅ/Ìäïß)0÷êß+iJ’‡÷¤`Ãjó 3~î8\†v晉›oÃwÞ„/{~‰Éb-„ïw+ׯ_ˆˆàøâ—ÆZ '°"?44Tøîo"|7ŒîDdÄ}w5ÿÅóÈÁ®ÖŒ%É,=º3ónñÝí«ùÓÙ*&²‡m»mð‡ï‡ÇëN5Âwá»ð]"|bòé‚‹‹5¾ÝÀMÒ*MæLm­Õ€àȵ3Ió=¾°ÖAÏtza?è, /pS'½ôwµá{ç°ÎÖÞàsâ´Ž;uiþRV []í9 ð7ŸþBÏ¿ü<øÞ:wz¹¼Ýîm¾¿þîëÜàù=yÿÓNü 4oFΗ®ðßÑgáÆm]m œëØ LçW5~bK1NàµUáKÃ"xq¦Î»äÉ=1?n CÛ%h•‡à Êà;=é…ïá{Çw„TçÉ©!0H;·iÂçdõú|T3˜9¥ÛJl—Kœ”àÄwÃâN;=èœljÃw„­D —ûqé¯Ò{@/$Ý -÷„rxÚ8ãþžÀ²^ç%àãnÅw÷ž3Âw‰ð½‰èñÝY vÛŸ 8Ï\8R謜¾8™Â{|d+Z1?žE<ÊhYîTæcó«û‘ðœ&óÄ$]hè¨c_>òz¾ ß…ïá;mÀ.ÜØ‘iè¶jfƒìï½ÿ#J=Þª¸´µ2¾`eG8º³S`‰GLæLâZSãRáiãßÝßæÐ¾¶KÀÏGø.¾ ßúûóUû6¯L[˜81eNh:½?ϯ†ˆGx|9l]³èÆérEžñ‘ß…ïá»at0·3x9‹Ì1Cå;Ê™#:èÜp¿ @ Z]’»Ø¶5æp¶‚« "ÒØ‚ºeX§ï»ÕÝ…Îî¨ãÒ›Üv] †dlc3ÞùVO04’6èGs„¬aÒ ¾»¿'¦´Ýÿµu&…K@áŽ/|—ß…ïRá»G"|¾K„ïaa·¶ú §û ΢¯Ùôù¦N[:Íê+oÔXœ¿j™k´í,R^Ήï#’GXkÂÝ„”ñħßì µu‹|Xîo­9ëÉëuâ»û{5G5ÙŽŒaâK ß%Âwá»Tø.|o*¦%’ïVõ¢U¬¬÷y«ØÖI¾œ—1׸°ÃZŒL°Ò%=;Y¾æÌ„?=mùì?¸K°ÕŽŽ³K™8b€‰€v÷±ØÉ¾8oŒ+Ž›y!Â:Û9ÄdâðW@6QÛêF=#Õ 8lp3#"ûºÇw÷÷Äæ]Ó%¼ n¬ùj 7p½ïx$ð`àñÐß½„ïR©ð]ø.|÷#‘L.Ž¥ì̬7çM_6Íꡎ)$K§œVy´óøR("¾›c•à›ÞêVìŠðÊ:Dc=¤ Ö}Öqi}§°Ô꼎1×ùYÂÈ3 ;ƒ/ D4ÍéÏ3•x]:½ ¦ö¤b²nðÝÃ{d7—F5\2“‚Ǽ—ð <?Á¿9á»T*|¾û¿üáþ!æë8]g³áŠGý¾Û¯4ÄkEø.• ß…ï^”?û³?Ã|q¸-_")ßJWÕ@Úƒ ±ØcÇÇb'ø˜ðZ?7ß$2v‚ÉÀÎ >F¦Ó&˜Œp¸3k ìÍušÒd-@dIlEå…çŠs”€Ôƒ¢âZØ8Ë£^Šè:¨†Ã¤àÖ‚SW‘sϵdkñ”E“qO’§&Áí9^U<x0ðxèoì]ɹsçΟ?_gµ+W®;v ÿzÒç­[·Ž=zâÄ ?y ãU‚†x­ߥRá»ðÝ‹òÿð˜ï™3glùÉ­Û7éþ¾úÿ©ßñxøÃßØË—/¯¸#gÏžeŽïåÝwßÅŒæÍ›ç²]û÷ïÿ·û·œ8þÓ¶mÛýû÷۪ݼys„ Íš5c5HóæÍÓÓÓÝ_:22²Îû™€ ]»võÁa²hˆ×Šð]*¾ ß½(=ôæ»{÷ng‘D’·mXmJÉ(a«”Ї ?ù»mÛ6vX^^ޤïeß¾}Àœ9sœ¥§OŸ~ì±ÇXÁ!~Ë–-¦ÚíÛ·ƒ‚‚ï”Y³fÕvéââbSÍ9ü©§žB…¯¾úÊk„W âµ"|—J…ïÂw/J@@@mo>‰äÂÕ³ÑéÝkK×͹JñàaÀ#Cø~íÚµŒŒ À±|oݺ5K#""¶nÝzøðáøøxæÀfoª%&&2óí·ß.++;yò$~Oâô/^¼èÒÎ}ß}÷¹ÁwøÕTWWÃÒRŸá;V ñZ¾K¥Âwá»…o—E‹¹,•H6ª`ï¼íéâצ¬y;Òù$à‘ðýßXø‚Ã=¦ø†¨íyÿu jZ½\jÃ÷šš 0Àšß£GæÃó‡þ?ÿöoÿ†dË–-¯^½jªáÏ2«ååå9ÇЩS'ëÕm¥¤vŠ/ñcÆkEø.• ß…ï^”^½za¾±±±µUHr·.´Åf†íÎÅ6MÅÒãÀc€‡ÁâÀ$008 (‡÷lÒlhŽ‹‹ƒ«‰T䘢çž{nãÆÆ•|ذaVû4zƒ·‰çý‰ýã;²k×.óI€Êuâ{xx8‹l;Vá6ÓýŽÀµIÚY-??ßfÝè£ZE…ý{iêÔ©4̇……¹¼ŸüMÀ÷øŽW âµ"|—J…ïÂw/JJJJÙ%’¹•©@·éÝò¶ÿN,ÛÔ‹Ž¥Ç€ÇƒoðÕœJ·x† šÓÏÆxiÑ¢sœ<ïŸbÜ]Ø–rø)))© ß_zé%äùå—VwçdáWƒjøÒÀ¨L5Oü…°Y655ÕåýÃw\ ñZ¾K¥Âwá»%''‡!<©,Qxèª-KD´MG±Ü\wz÷1¾Ó"¾páB`(þXÁdÎÌ™3grÛhZZsæÎ ®¥“ œU˜ Ó5ìñð§+9yÝóþÝ໑½{÷:ñÞ8ÌaÃ~ ˆÑ`zü,`ugç—FûöíwìØÌ­®ø7$$t:Üó«¿ éÄw§àÃÀgøŽW âN ߥRá»ðÝ‹Â_ÿê¯þªÎšɪMóHr3Ë“jU mÚŠ%ÆBsűô||ïUUUÎýš@áÚ|ß‹Œ{à¡H$7oßÈܼ€´›ÕgÕæÅ"à¯bù°ˆ\M,+KÜèøNÀu Ù¹s§K|§2®ê î¿þø~ãÆ æ÷ïßßÖq$Y‰d«V­j;ꈻT±·Õìpu/ãÆk,|Ç-¥ã;^(Âw©Tø.|÷ÝÙ«Îp· %’ƒgvM/%ö%æôÇÁœ?®]­ÚŸŠ%ÃÂq±”XP®¬?à;¬Ë¶"ØËY>vâ» =AHGæ˜-­­ïȦM›<î¿þøn¸d˜tšÕiûGîFe©3|;{€ËÍ}1~óLb …ïx}˜á»T*|¾{_è-ÊŸhë%IåÞüäÜD@èô²„Õ;V ŽýY±@ÓËâÍ’aù°ˆu.´ïã¾›ƒHAšq‘glû;£££­ CCC™H2öß@|ç¶"6gr:µãXVs¤  ÀZmýúõÈtFž*~âûNŸ%¼J„ïR©ð]øî#AúÏ\¿~½ÞH$[ÖÌ«m!ÂË×ÏZw¸Z¬ì?ŠåÀ¢`iÌ2aɰp\AÃwÚž/_¾ÌƒTÍ!£ÀVãûg«›¶°“›+++™ qVCdwÏû§àXÖçîȆ î ßqJ+‹^ýuXÜ™ FÇÀ˜iˆeìHp6ràÀ\‘³À÷†Ÿã;^ôœÁ«Dø.• ß…ï¾'ž4iRû‘HÎ\:‘¿m™ÙØ•öõŒò¤‚YBçÆU,ÁŒ²$,×%!»/–éô¥ï±Òoñ£8©—ÝQÁ†§$]â¯ñ_§Ì ôh÷¼ÿzÛD4hKiéç1± ~70ÕÒÓÓ­¦ÏŒ9Ž üßñâ`„{&…ïR©ð]øî»ø3÷öøU‰dó‘5s*RŒ•7%oð‚ꉫwfФ}©¸á¸í¸ùf!æT$o>lŠè¿øŽ˜‰<ÈÓ\ÀOœ8a­œœœŒ|aà l…`nE0ÇzôŸ˜˜hóϱoýwËÙÈ·Ç„+þ?{ç´$éásÕ×ý(ýýcÛ¶m{¦Ô¶QfÛöØÖñÇ©h–3#/ kå`eTìmfÍlšŽqŸvµ“qœfpðæoÚ÷Å‹G®RDdßEQö]ö=Ú0š WTTük ³wcm¶“¥Âöñ`áòëõGrºúëd¯#A„E^DFê°ì'K×—·Zùã0þ\âß¾‡=1'Ol6[vvö\Ý`¸‚´¥¥…'Lœvõ)?ló¿‘ÿÝõ#Ž×ãÎïÞ½[TTr&hÉOò&“Éjµò‚C5 Q†‘7|O­ì»(ʾ˾GÜ¢ðBäÐ9ÑHGÂËÕ{ 7iðdÙÆûîó¥m9¡‘À1¬""#b"éd…¯Ôì-m1uM4ýšŒ²ïÀüë †8ÿ¨Ý;åCö]eßeßc. OKK#ýÚÚÚÈí"¯?> ÔYý׎—¬l4/Vï±nÖv—É‹ÿ}"¢!Ýd%—¬³ù¯ë_|ñ+b}—}§X0’ÂAù}EÙwÙ÷Ø€FH?333Z jßSÛYîÿçÓ®‹iB÷IZ’Wvú‡<†U‘¢²³0;tq¡&놌ˆ9ü²÷WT û.ûN±˜|5•ì»(ʾ˾Ç!MOOG‹ÅÍ}áó·O´/,lzx¡ÊxÈr ¯¹R»Ÿ+ý‹Z,öު汦T0ë¤I²¤Lâ¤3•A.Dk ~ù6©y²Ø÷Çÿ»]¢°¾ì;e‚a” ‡ì»(ʾ˾ÇtI3zœÅ*Aøòí3¿Êûûk0¦·íÇŽ¯ži[ÏTl½í8™ºSÖž[ßSár'ºY'!’"5œ™5RÜv+jzä¨E¢¯ß?'«5ŒȾ½}(¼–}EÙwÙ÷øôdÛ¶mq ¼úð¬c<ÄÉ‹ÿêŪÙYy¬d-¯×~à>o Þ*l6qöÆÙWŽ‹«£ƒ`‰À •€ {®ŒHÖâ¿B⤩c ã²ïÆP,x-û.вï²ï±‡ÑLϰ q‹oß¿¿êåù×âæÇ=ç¯Õî7SÎÃKiÉÂ#ž·ìÇï»Ï=ò^2ù®Y79^OÅ‚fSq‹µ¬-§¢£ º«¸®»ÜÑ[MûEï 30ìm 45B^ð–ùŠ c0ShùÂô‚æ',Å‚,ËâlÁFlǦlMóGH $B:$Ej$øõ{<Þ‚,û.ûn<± (²ï¢(û.û/X¿~=:ddd-Š!þñãç­ ¿ìi xú*i6Ÿ¼yÏyêbÕ®#Å«ðÇ1'a !á$¡r†° >¥¬¡ÿ˜çÉJ(¼Mû‡EÙ÷¿½ŽÐWm Bœ§þ~¼ïy{ã°ËÛ_íì)«ë*¬jÏ.k1sÂ>7tǸnò^âFÒ;Ž7êÑ.§BÏ”o>Q²îpÑÊýùK /èÉȇ*w0€aw'˜ÂD¦³HQÓòVKU{‹³…¯¿šíØôù»qãÑRá!ÁíûÂ… ãôØŒì»(û.û.ø|¿Ù»_Ðå¹(€ãgeá¦%ƒiÅb²Ü´bÖ°õ2“ÕbÁbaX]/K˳˜4 6ƒYëÒ}aL/<ÂïÑíûé/—sÏ99Ž#"I’˜Ö$I""ŽãœN'˜ïHÓTjyž›äy.µ4M ï~ÈI)U–¥´RY–J©ï8Ò€|GÇ"Òív/—‹´Ìårév»"DZòý+„a("¾ïSðжv÷}_DÂ04_ùŽÑhdßà™¢iÌÌØw÷Ñhd¾ò7x¥?YÛU•R¼»7@¾3Ï6É6ÀŽHæÝ› ßÙEc/:q“µIÀÞUµ·™Ø3Ó(ùÎ>x{Ñi0GÓ€ãñ8 ìm&ö»7 @¾s“Uk-µåri_n¹\JMkÝÌ»ªÈwÌçs©õûý,Ë à eYÖï÷¥6ŸÏ ï VÅû~<3Kß5-3ßîEQ ßÛ`»Ýzž'µ(Їƒù`€ÃáE‘Ô<ÏÛn·È÷Vy½^‹ÅÂu]©A°ß﫪2PUÕ~¿‚@j®ë.‹×ëe€|o§Çã±Z­:ŽÔ”R“É$Ïó»bX™çùd2QJI­Óé¬V«Çãa€|‡].9Ū;>Š¢$IÎç³üˆóùœ$IE¶Ú­ápøÿK!€|Çõz]¯×■`:n6›,Ëʲ¼ÝnÏ糪*éàOŸÕ«ªz>Ÿ·Û­,Ë,Ë6›Ít: ‚àì–Öz½^_¯Wä;~é~¿§iÇq¯×Àèõzq§iz¿ß ïøëùø¢(v»Ýl6 ÃPkíû¾çy®ëÚc®€ßä8Žëºžçù¾¯µÃp6›ív»¢(˜k@¾-b§ÿÇÞ­a>®Aî¹K{s{sAÎAîAîAº÷Cwî?5]Úæ?σî¼»óÚ·ßï‹¿.‰DF‘x¨ïð%‡Ca±X.à F¦‘¨ïíàù|Îçó,Âñx,\†ŒL#!ITLõ½ìv»lÁr¹¬& $Q1 Ô÷Np¿ß‡Ñår©&a”ÀT?Ôw˜ªÍf“X¯×õ–ÃDB’™$0Õõ}’àz½£ÛíV¼½ $$Ã(±©f¨ï“«Õ*ùßn·Å—D%cIlªêûôÀù|Nøg³Ùãñ(>¸ $* L&“ðT'ÔwðO¿é2øÅ õüÓä0á'Ôwhû§ét:ÿyHl¾î'Ôw& (Ô÷V¨ï€ú ¾#šý[ ¾ƒl€­@}ï‡l¶@}G4û¶@}G4ÿyü£ÏŸ?oÛ¶­¹¹Ù××WLLLKK+66¶··wÏž=ìdjQÇÃÈ` 3ŒŒaÆ*TêDÐIB’‚"”T’TRªB¤ZÞ_‡OuoGÚÚ{ñý0wç|§sïíÃïœûm÷ós9²ÙlZƒAÉ,‡1âÝI“ÉÄf³‰QÃáP5¡×ívos ívÛh4ÞÜÜœžžj4š‹‹‹§§§x<þOþU¥^¯×étårYéñx‡+[ƒNt»]I˜ßï·ªïÝçóåóùÙl&Ÿé$†¤ÓiÕ€R©d•"ò'•JY·ã+/X¥KŽF£¬ï Ã0? ë;éY«ÕàëG¸¾¾†Ã-‹¾h‡å“Ù¯‘ÍfEÌåå¥x#=}Úëë«êççgôžœœàXŽ×ë=>>V=U­VÛétöwëF£ÑŸý~_´`:1u$‘Å­@ØûûûaeKµZX,%açççGRð•IÖWÓééDù¦äSˆü1›ÍGÛquuµóm¡K~yyÁñ·ƒtBšaMÈú¾Ã0 ë;é™ÉdÈœppo±XL&,Š,V”ËåhÈÃÃhO$ªS`¸ÀÎ+é;íÕõ=™LÒç`Èï8 K€TÇã=ݺB¡ fÁ/뻪¾kWY[nzb …–ÃðtE¢ïHKÍpxÊñkúصv¤Í«ï"Ÿñì‚õa†õaVr£ÑhÜ<>>bg}9²^¯“–ÁPC….¢ñííMu Ô´ˆˆ»RßÏÎΰۺ›¾ã|„ÀU*•åö^¯‡²tÑ+W^ßYßáÄÊ.¬¦ìv»|ÃûîËå’è{,£Æm¸½½9£ìb}g†aXß™KMؤøÕ`0lªjÞ Pµ²VꀟTÓ¬¬œAõ¼h!}'œNçúŽBs1·þøøPöÎçs¬FZ­Ö¾õ6¨5’è;…ᯔaß~ÎJ°Ô¡ª§MÐ×úE}'(‹þ²wžZiîïY"@‚‘QDÙK¤èŠH‰RUÑJRUÙÒ½*¸RѲ’„D„ì£×>¦3çÓ÷]·öÛ÷‡œæ›ïœ9gæsŸ™ù½ï©gn¸êã#6mb\­^½úÏÁwº˜‡À$dÙñ33&Ã÷¯_¿ò$¯ÂÄ{þ"¤R©Tâ{*‡æçÏŸõÌ@Cõ_¼xÕXS·pÿþýQøäÉ“!çŒašâ;8 Çñ‡~ßEÉ“'OöV ˜‚Ô^/s³è ½y³ WAûñãG¾…–––:AºQþúõë8¹ç€òW¯^‰ïÜìéÓ§ ¢õYzûö-}Ç<ß‹ïÀ1áÑñ¸Bk×®u´×øNØ7·¿mÛ¶Îy:DyT“§¹M;—úÚû=vìõýˆc§ÍèÝ»w[¶l±˜…(W:»[|ëåË—W®\‰«Ü¹s'ÿ"¤R©Tâû,(‡æ½{÷ú×Â+éK‘òƒ(Ù½{wíœ â€ÄwM¬RÇñÆÛñÝ%aðÀ¾ø/Óhãzæ6eÞ÷š&5jÓ7BäúØH~ ¾_»v­w<|úô‰çƒx ÕÄøîÖÓ… €u)üß?T‡®Äßb[ ×SälG|÷ó/B*•J%¾Ïšrhê0 ã\wÄ¢P–%F±ò'‰’(pßÁW£I<߈ïJèÁ Bèž(/I—sùòå¡ÌXq–ßÅt…)«—øL×wáCklóø^?XB$Åw ÙqÝsçÎõÏ.šWßÿVþŽ7ãòQ¯mÍ=ÿø¯Êüî¥-ÊrzüŸ}rYzJ|w´{ÂZã»Û2Ñ$ÚÆÂí¯!|wªÌ(šÿY±*˜u”ÞyWþEH¥R©YÃ÷TM0(ŽÇ_ü^®Ó÷ÆGùÇuÎÈ=#øŽ0‡PFÔ'À÷Î:.-1`¦Qï(0+`hßYdmÇw¯2Žï8|†¸üÀmÇw °ÆwŒ+Cøn ²;JËõ”¡«ÄFÇIp •å,º¯íYùÐUiýéñߎønˆpFŒ‹É݉ßYY_5,—óK|¿}ûvþEH¥R©YÃ÷TMbæâòxÞè:q¤NtWOuÎ`wæxß)5¢üÌ™3ãøn¶JQD-à8NHBÌ5’÷¾©jßq™·ã»ßÇw®X'w7žµ±Í#øþåË k|+GðÝió±Nµ7oÞLï4î4ÃGGþR)>bñ~åñp^'«Óã;\^â»[.Ïž=ãõÆÆD ñ\õâ;;TQ‡ÉÀßD'&¾§R©ÔŒã{*‡&ΰ“ ¥Ù]¢ÎÅ‹ëOItäA 7ññ%s€Ï0ÁÀ÷–8`î¸GÜÑ”Bû‡ ! ¬øn`n›»œø^ã]¹âÞÞfñÝ ?Ç'Àw:¢vð;‡™ß9s:˜³Å™IY×—kIW¿Âø~üøñÞ†1êþúCL‡ðX¯çfâ;ÿed¢2ÚËû¾}û´`õâ»î¦:¯<#-Ή“>ñ=•J¥fßS94õÏ@Wõût^dS­ uŒ7QAGñ=}ú”r5Žïzu>lamÆ0L[Nœ³ójXšÕ?~/@-‘×cwÙñEà£Â3圪±Í³\XgZƒG{Í3nSààâÄD¯‰ïNÏxPAÛ!_«ôàÁa½ój3gÚØ¥8¿±¿q fGQ’øžJ¥R³ï©š,ºÇÊh-±ixÇüÑŠï~Ê%Æñ½6‡Ø6xHHBü•Ãô`Pðr‹@2 ñzüòœn8”ø.Wy¨z|÷*å]!ú«mæQ×mž ßÍä…Ø‰;åßéñÝÌB“•s³ÝW2EºùŽVß=ÎWœn•]@c:ønZI>µšÇâ»Àm~wÌj|Âô‘+÷‘¯¦üÕ€ìtŠÝÍ ™x{*Ío‰ï©T*5ãøžÊ¡)º:uªBØâ}q¦TÑÙÙ×ÝÛ1BÔëF|GdÙÛ¼ysÝTÚÏDžî`´/RИf(!ËùeuëÖ™y¦„fT™ÈœW5õfïÑM΢iiæÆWÑ &›¬Í¥›È§‡[#(üĉ¾»ªßÙZß%¿ÈB¨Dz¿dèqk»ÎïZ´‡ F6s]ß^4$ŒàåT„ýŸÒ>Ô"-Uíø®èýàc¯ÇÜÃ[îd%OÜ—gËÑ£GãwT¿«t ózSGä;­Qã.äÇà1ú9ÿ"¤R©Ôìã{*‡&ÿ²yýúu–Eeñ?PÄ...ò¦}Ò¥cA¤Í^ >^XX8þõ˜ïíáAøÔ˜ïàl€O=æ;ä€O=À"˜ï€)×À|óÈ˜ï° ³†ÿÊÊÊüϦ¨›8¢qPã]C›¨™ùÞt:8À­Ì?߉ƒïjÚ @µÌ÷öàòò2NïÆÆF¦’ùN×xcãèfªe¾Cïïïkkkqz¯¯¯3•Ìwâ¸ÆG7p Næ;´qzzGw{{;SÕ|'m¼·q€352ß¡…———Ô¸½½ÍT5߉C›qŒ3Õ1ß¡…ýýý8·{{{™ ç;qtãícœ¨‹ù-Üßß§Æããc®ùNÝԈÜ+€ù-ìììÄ¡=::ÊÕ2߉ïpæ @;æ;è4áfPqÀ|&ó'OIó&Ìw'ÌwÐiÂÍ â€ù:Mæ;*Nž’æ;:M˜ï*N˜ï ÓäbBÅ ótšÌwTœÌwitš0ßUœ0ßA§Éńп;è4™ï¨8´b¾ƒNn'ÌwÐi2ßQqð”4ßÑiÂ|WqÀ|&Ü *N˜ï Ód¾£âà)i¾£Ó„ù®â€ù:M.&Tœ0ßA§É|GÅ À|÷F§ ó]Å ótš\L¨8`¾ƒN“ùŽŠ@{æ;è4áfPqÀ|‡Owšîîî2æ;ø8¨8µ`¾ƒN“‹ 'ÌwÐi2ßQq(˜ù:Mæ;*N滇4:M˜ï*N˜ï ÓäbBÅ ó...tš>Ï|WqŠLþ˜ïðöö¦Ód¾ÿ[*NñÁɘï Ó„›AÅ ótšÌwTœ<%Íwtš0ßUœ0ßA§ 7ƒŠæ;è4™ï¨8,ˆù:M.&Tœ0ßakkK§É|ÿïTœâ£”0ßA§ 7ƒŠæ;è4™ï¨8xJšïè4a¾«8`¾ƒN“‹ 'Ìwtš0ßQq0ß=¤ÑiÂ|WqÀ|&*N˜ï- Ó„ùŽŠ€ù:M¸Tœ0ßA§É|GÅ ÀSÒ|G§ ó'ótšp3¨8`¾£Ó„ùŽŠÀâ™ï ÓäbBÅ ó&ÌwTœ b¾£Ót||œ1ßùŇNÅ À|&*N˜ï- Ó„ùŽŠ€ù:M¸Tœ0ßÑiÂ|GÅ ÀSÒ|G§ ó'ótšp3¨8`¾£Ó„ùŽŠ€§¤ùŽNæ;*Næ;è4¹˜PqÀ|G§ ó'€0ßA§Éńп{{£Ñèììì—Fú yÎB_ã5&ïÏ·yMjx¾Ík>*NÞŸ¢^sxxxssóúúš[Ì÷Zt»ÝôÁ|/à5…Y]]uš¼?e¾Æ|÷šÙÇ3>ªñõþòš‡‡‡ô»N§s~~^ÁŽÌ÷Æãñp8œL&qñåprr¢Óäb¢–ŠS|`s˜N§ñ8ëõzKKK©ÿ#—0ß[ÜkƒÁ ðŸ¥æùù¹®N滊S|l3å}3Õï÷r!ó½ÅE¶¼¼œRŠ3:M˜ï…PqÀ|ÿÓ_åIn·ë«è4===åâa¾Õê*N¾•ÏEÌ÷y½^/5®®®òO¥Ó„ùŽŠñL)íîîN§Ó\À|ŸÿMüõõõþk©:M˜ï¨8ÂÙoµv:/Xð€ùŽNæ;*N´øJkö|n 0ßá£Ó”q1Q•ùе|? r €ùì4e\LTe¾â”©dÁ—òk¬€ù>NÿæÏË Ó„ùŽŠýì;`¾G¨"¥äK&Ì÷Ò©8`¾Ç÷î©á x&Ì÷Ò©8`¾ÏþÊ»L´Næ{éTœ0ß?¾z÷#}:M˜ï¨8ñÉ‚Fþ“5| ó}8¦”úý~F§ ó'>÷ c_ÖÜÌ÷Éd×Pü›ÑiÂ|GʼnOdzkþG€ùŽNÓææfþvp3íŠ*NÌ*N~~Ìw¨ Ó„ùŽŠ½^Ï\†¯d¾óëoì…vÛÅÿOÑéòÿÕ7è#\w­» qOˆ»•¤ÁÝÝ!&Ä­©[Ò¹ßbZê.a&û·v‡9{o¯ç›û·¯\_š¼’ŒÌ¹|S&gZkeƤL;Ú¯Œv‡Ú¯¸Û]Ñî(n²‰ȩ̂ª GËuŠÔ»ó”ŸùDÿ¡‹eºtÝ¡É*jsu¹ÊÏ{kü ²P«<Ò¥‰K ‰!KjÄ1®öLâó¾™ef忥ûë÷pž¦g€¯NH$½¿¯ÿÏâijùJðdwŽÑß,ñ|$6l¬ÝZž]I'T‡ô‰Ai°¹ÃYZc<ž¯úçÔ…Ÿ7]…ªµ¦®2Y°EŸ¢79ºà§7¼vëÊúÆ}îlM8OÓ¾9u'†aà+^ ¿úê«––€øÞŸ{ëwçV'ÓVU¬·×SÕ`9S¢ÙûêRtVþ{‰v_éd‹½¨Ó]ÙãK| æ¡Pûp¤[;¯Šh2ý˜ÜĨ¬ã:Ç„É5eõÎ8sÞð| ¶!…çƒt‘®tOÙèÖ´ÎĨ crmbX5:¨ˆI.Dz¤¡Ž`KŸ¿±×[Ûå®j²TiöÐbØ«ß!­“Ñ -§Ñ[xÖ¹¸6³ñ`ð|_m_âû‰ ,ÿY½yyl)dIÉûýu5Æc/].Rïª4m´åQ¢šDõÉ0¦pNšƒsþøRlÓE¥”Š(•OyL2hétW5Úò« GémŸùå…ŸˆV¿ü VF1¶¦ƒÀ‚\ó|à+ø €øŽq÷ÖïÌ®¤ýÓe´§ÕQX ú÷ù:Q®?Ôê( µi“ö´Þ7ë¦zÃkùg=ö #-ŒÑ[³½°TwàùO] ú§Õ^ ty§LÓËÌí{Ø_ÁWð•à|ˆï|Ù˜X *¢ÝÕÆ£/*;ë,gz½µÊx?ÕŒØb”ê‡à]ÛÒZ“ëñŠëÌgè <dĦªX/­uÑô,€¯à+øJ(¾Ä÷eneÂ’’S?„'§øÓ#¿Vè·9K¥¡vCJAË<\y€èPS i¨£ÝYVi8rVþÔïSÛÅVFA¿²ey|_ÁWð ¾çÔo!8cô7Ðæ§'gsÚ§Õh¶Œkß¼<@fFÓçoª6žxfWÙ€¿¶Ê ÿç§ð|_ÁWÝ?@|ß|˜‹QM\BÍ žœ¸©»íˆÒ$d¡ùÀûT(4ï×$¤Ô¤‚é ¿­fù|_ÁWð•Àk(ñݘÝT.__Ô”höd'èsŠ?©ƒµ?£Ng£0@t`éð6ÙòEŠ?³‡½X³›âòõ–'ÀWð|_!¾ó ßùO|ÞK]³Ó1µH“øLŒúSĘ̀©©sÕÝëhPâ >ø ‚¯à+øêãÕîÿ=ñ=×Y¾qј”–>úJ”:·;ËÍŒ•ise×v¸Êi›7.eºý¦±á—ýؾ‚à+¾B|'@|8‰Å@¯§:»jBÝdáÎм¥(wšРÐÐd‡Iâ?ÿKSø ‚¯ øjb‡àñ=wñL+ô‡²3l›³Ä”R¡ö䲌)e«£$;dU†£Î´¾‚à+¾Êr<ê>ˆïBcve<Û¹Lwp(Ô˜ó¢Øð¨1ó`°­T»ŸÁ{Áô2_Að_q î€øþ©ù:ûq¸¿qO—1HSa‘z·5­GmØšê<\ËL]ŒÀW<|ÁWüïápøÈ‘#ùùùÜE³ÙLÅb1Ë7 î]»vìØQVVÆ],((èîîfyÅÚÚÚ‘ ËËË,@|ÏA¢snn4¤¨ [Y=^1ÙàœüÙ•qø ‚¯„$ø*÷ã{gg'=Û¶mÛ¸‹"‘ˆ.nß¾_‰B&“ÑÛæøöÛoéš;wÒÿ?ûì3~}©©)îS¤R)^ë›7ogX]]N|G|¿v{U¤ø“&A:7!êÔî,#3”hö’1à+¾€à+Ä÷OÉÏ?ÿœÍîJ¥ñ}ÓI&“Üq¹\ˆï‰”¦¿f{áìwtUG–îûÿy9LÎy:‡Å$?Þðxã=ŒÇíÍã™ÆÏ´»ÁÆ8`LÎ9gLÎmd ²@D$£L&ƒœs&¬ù­»—÷:>u%‘@\]¾½öÒÒ©³«Nª½îþή]»d ŒÅKŠ'¡(†ôJ,½g½^H‘àûÍ¢6mÚÐínݺyÉ›o¾ ‚¼xñ¢àûÍ!ÁwÁwŽ¡ž¼ý)~û OÈ ‹QTbÊö§¯ß¸.½K¯ÄÙ­W·×î_¿~ýÆIàûÕ«WAÀ×®]kÚƒÞzë-ðèçŸÞ€ÌG}töìÙ/¾ø"Iƒï¾û.¯¾?õÔSÉGà¦ÇŠÐ·°üã?f ­Î7¾Ó>ß*>¡NŸ}ö™|£ôå—_Òÿ°Yñý2ùÜ%‡ï|ðà{KS»5­né™]vN¡l€8ÊÏ޲¼lY¨Wbé•Xz•ð}õêÕwß}÷¿OÑ=÷ܳlÙ2JÒÂ÷S§N!ÉÿFíÛ·¯©©I(Éjÿ»¿û»^ÀP\\¬l-ýó?ÿs—‚ïÚµ+*3mÚ´ï~÷»|ûí·{öìi Òó:TVVšÌ’%Khœr»Åÿ¶ wþüùüß·oßhƒGŽéܹ3/‹p§NæÍ›wåÊ•ûRäP•aá¡áæ]ä)g¸ìrÑ¢E\öéÓçòåËT¡Áo~ó›.|îܹ‡zÈ;ŒÀòåËÃ:pà@×®]­?ÄùŒ5ª¶¶¶QøÎ»óhætÞ¿“ã7üCâ¹çžCÀÊivôèÑ1tÞ¥K:&¥{÷îôI:™››ËÝòòrŸú?þã?eÊ»j[û”¾3JiG}üÜÞàæÍ›ÓNG£ð¤:&Ó»wo¯hðZt#löoÿöo_ýuoÁd¬ç1ú‡… &µ’Ï]8_>õcÆŒI[—o Á÷L‡ïK‹'ð«·O+Ñ_gñ¾S;PŒ¥E²[¯ÄÒ+±ôªåí¯ƒE [AAÁéÓ§×­[g`1„ïÚxíµ×/^l%@ØO?ý´áùGži|®ÄW~Äà,öЋ.\À‹LˆPØ ñÎFá»>Ú£GÒ0¢£adpÌSh(œþ§†ðB… à†g‡«á׿Àw#áãÆÛ¸q#å´ã^gAX Îr¾(¬Ð7<à³÷ïU«V±ÖAÊN@6%Éá»M0LcˆÜ‚ˆ … òFƒ»>ß­úÚµkÏœ9ƒßK§ñãÇóuD>ÿ¼Áãž|îâÆJhŸnXO~~¾²~RUUÅà ï}ÆŸÑð]ðÝI«.•ˈ£\}©Å@=²X¯ÄÒ+±ôªåí/®w ¦aJ¢±½ŒX|6lX´b?’xI/]º„ŒEbxÄ…û\ %;r}ôÑGcqítÏÐp ¾ƒ•ÃHwóïs߉¢±¦***¢é¼x3á;Ñ8Ñàï^½z(ç5£¡ö<ð€³…ÂûG.Æ.'‡ï WÔ§P¶rPrT~Μ9V~ìØ1‡ïa`:/b…S§NõBb„¬ .“Ï]ûÎÊogKþ1`umlÙyœÑð]ðÝÒ'8·O@åÒóE¦Ù­Wbé•Xz52E-f?nµ–.Gû˜c8„ïxÍ£b T ©ÇQ¿>ù:™{•c’¬úÎ;£Õ íèž"¤Ë8štrÍã¢ðÝ?9Œðë[Ÿ“Ãw—t öDÂß› ßùb‰~&Y!Kõe¦·=6˜aV®\™¾ƒ×£åYeaèáb÷©Gá;1N1Œ…ÑC v+´tœÉç.„ïÕÕÕVÂâO¬.çmyÝL‡ï‚ïÇ6ʈ£¼óøK¦Y¬Wbé•XzÕò°Ãƒˆ? ñk¾[”K@l74·ºç«q²½­Q/»ûžCb'e |‡>~ÀŸCpwLÌ:™¾ cøÕ©¤¤¤éð=x ÞÚƒCÌ+€Ùà!.á!¸Éá;PÑrÊ7›Æ(näðÝÀ±Â¡j‘XÆ·=$Ÿ»´ðÝãsxn¬{ —Ý"GðýÖÒÞ5ÇæV-–GyCõrÓ,Ö+±ôJ,½jyØA«Åφξýôù`lBøî2¸–èL=B'±>{k Tíœ'6¾;%Üß<MBøÎK…ðh¨ žõo4FÄ©ûC7mÚ{ ÝHß-rƳý4úhN1ø>tèоóš À÷äsÂw¾í!ËD‚ïJn9öB@奩“Pà,Ö+±ôJ,½jyØážQôpM†ðËÿaæDn‘sÐPÝê¯è-zúiÇñCÇü˜½1ÞøÎIkvÆ ±¦@¥Ià;'ÿSØ(|÷ø€òªzèTŠ<ú% sj|÷¸öãÖ÷hÖßý“Ã÷äsÂ÷Ù³g[ ÓW_ ÙÊtø.øï?½S6ÀXŒ2¸bH¯ÄÒ«ìféU ÃŽ¢¢¢ú’{X¢À0öÝ3…{ªod‚¨î8±ëÑ]°±-­÷¦ˆ|&Žó8W(VÝöwBø’o"|‡ÂM™FcÇŽ á»ç@t"MJøîQ1<òˆúæê‘º‡Mœžˆ&üœh|‡lw2ýp"&¾™ð=ùÜ…ðÝ#¸€é±º, Ñ=‡ZÇÖUÁ÷å¯L“0£ ®Ò+±ô*»YzÕ°ƒÍˆ±ð O½\K ßÙC•d»a˜Õ¤ ÚñBÓnl‡q~’‡Ðù¹ðÝ -hÛrž8jô åß-i=þ±l˜Ià;äG5ùƒŒf̘Ý€Ü^(l0h"|'¦<ÌfcÇ08>Â,zàÂ|¿åÔ.EÍ1‡ü.+™Â?‹ŠÆº\ugZ1S¿hÿxÔeàÒtCz%–^e7K¯n‹Ý'lÃOÇ4êÚµ+.ö(6Wè}÷Ý7sæLGZ&@üw‘Ü1«ƒ3B8bÑäáÑú'NŒz÷ûõëÂwëdß=”<¬ëŽ^<ÁŽ)ù§wïÞíƒK><ÿȈ~‚} mƒq=ýe¸‰ÓO_8p`ìÕxãól’ŽhÁ÷Ñc’ÒRaa¡ÉðIÞ%§§Oœ7»uëVðÐ?yÀÃ{BøÎ>TšJ>w±½ª+0žZÇö@;ñD>Šle@ð=Óó¾›9t‹ø|á¨Ê‹¥wš%3éó G¹-ts(½K¯²¥W`ñ “Û„Àeœ©¡ïÖÉñ.˜›Ì’@IY¾À|»wï>wî\Z¼­ä¡ÏÉÉa/#ˆÐ\ ñ÷o¿ýv,ˆ%ì!ôŸ8òXxzBâ¼;‰}ȉ»>1ð:|0ø 7ŸI"[ãal ajf³Í™;bx»xñ¢÷Á¿ ˆŸá1F˜SW­Pð½5Áw·ˆsö ã»;ÉèÌÂýsö u[šCé•Xz••,½jyû+â<)òÞôïß?Lfï‰ÌED™ßßÝ"²èåÚ¹g=3ÑL·ÛÂÐJ¯ÄÒ«leé•à{˱.âþc„¬0Ä-‰ßß#übå"+_^2?G[9±˜b›k&=v×Ê¥WbéUv³ôjdŠß[ŒˆÖ VÞ7ÔF÷tâ€÷$"Á÷¤$øî¼óøK3vàÖ¤mOn9ò+YŽìc¦•ÉeŠ™h¦;0Ý^‰¥WÙÍÒ«–‡"‚°=ùŒïI%M¤°»àûß÷¦èæšCÛ´òÀ  9—ýbг€™J˶3Åõíü3é•Xz•…,½|Ï"[KEEÉ[l÷ê¿D‚ïÊûÞ Ïã…)O›Ø‚}c¶ÛØzÍ€˜écm6™V&·a“^‰¥W­‰¥W‚ï"‘à»à;\}©|ÃÁåÓvô7áy{Gæ×æ¶.3 fʘ8›A¦’ eZ®bÂÒ+±ôª•±ôJð]$||÷326Z=s×@«BÞ®W(_[†3Ä4Y’5˜écžtcU¤WbéU«dé•à»H$ø.øn\så0+˜³w±Šð’âIùµë_®–íÉf:˜¦Æ§‰)c☾äXEé•Xz•Ý,½‘"ÁwQÖ’à»à»óŽã›—•L“÷˯ŸùUÙܽ'·ÉÝ^f ˜¦Ãæ… bš˜¬&4e-H¯ÄÒ«ìféU&Û}QIIÉäÉ“9µ4¡¼/úÁ4*öé§ŸrØ-“´IJœºº:öÚjFßoµKQ ›C_ë$*Ñ[vbNÅ‚]'¶j9ÿ–|WwŸÈË©\ÈàGÝWLG ´˜%½’^I¯¤W‚ï"§Q£FYzøF%9ðРAÿþßÿ{›þ¹ï¾û.\¸à~DÔ¢E‹ÈS‰ŒÑ]wÝÅRIºÑð\Ϙ1Ç{Lð½åê*ï{3y׉­+^™>îåÇüçx|þã‹öã¹èô.Y¬[Á%g÷¾tx +Îãóûø°3LÓáb­fI¯¤WÒ+é•à{r|çwAÒÉAü±cÇ\ìúõëݺu£<¤5kÖÔ×xqq±‹Õ'óÅ_|ó›ßDà¿@[ ¾ ¾W\x%¯&‡Ÿc;Ôö¥jNË{¹æEKÙÛdW]*+8¶qu鬩;žµ±õä dDΫy‘)0Él€YÒ+é•ôJz%øž€ßï½÷^›‹?~üòåËÓ§O··r±™3gZa§N8ðÖ[omÙ²ˆo@ÿ£>JëÔÿÝßýÝà;q5UUUxú¹ÛÊà»à»à{ÈûNíÀ•µpÿ¸ˆ‹Ë’ Z[ñüžW_FFœûÌÅÖ¯_ob{öì ïÒ¥‹ÝM;׎Ú!ÁwÁ÷l€ïÎ5u‡w¿š‡ ôt`γvÆõEj0~î«_«0y1CÁ€0, C´y{G¬«^Zxr;ëU²fI¯¤WÒ«`éÕÈ ¾'¡7ntèÐø[ZZJ´ >lBɧM› ×ÖÖºS:?ú裶©4¹LßÏ;×=EyyyVÒ¯_?«kœ°™>)"´†Kí&;¨þóÏ?è#VVV{_¶Ìšcþ™gžI;×̾ ¾g!|èm-uš¯¥Fxòö§ ?Åm³ýèÆçöß9ö—å•yq^ŸAG†µæ5es8<üàk•aõì‡YÒ+é•ôJz¥¼ï™ßí•CØja*D’˜äÑ£GCúo¿ývr™¾WTT˜Ø¤I“¬ä‡?ü!—àþ¨;?ìrå`k·|¼/ÂëðR¼/ÈkÆ^œ¡`@‡! Ì’^I¯¤WÒ+Á÷Ûß d¯[·غk×.\òV¸zõj“4Ç<ˆ¶¨¨ˆHÂʹe2$~I*“¾½c— ìmÛ¶Íb0LÏ¢J4œ½mÛ¶”?ðÀ'Ož|øá‡iÓZîÙ³çùóç]Ì]òöU€›ŸË¾‡Ä‡à{‹ÖUÞ÷ŒqêìÛ~tCÊ©3Þ2‡çANÅ$2!|·T3ßMÑÊ•+­äôéÓV¥cÇŽxÜ­Œ ·B+¡Ÿ´ctôÐÅ‹iÊÐ?]||‡ßÅ‚Yb±ôJ,øž…ð݃Ô¾~ꪵ“ÍÝ£MG¹÷Þ{]ŒŒ.Id’ŸºêIl|e€#¥<dÔ»ŸŸŸïb´‰¤_’ôÁwÁwÁ÷Lg±`–Xz%–^LQryÁw˱H>õ(ŽGs>â;7?zŒ† Fp|r™Ñ£G"÷–IüÍóèþŽ%±¡‡ä¥q¯pí § ‰À›„ð½W¯^‚ï‚ï‚ïbÁ¬Ìb±ôJ¬¼ï‚ï`eÛºqãÆÍ›7{¶'M!ü¢E‹/^Lz™ººº¦É$$‚p@ç«V­Ú¶mÍÒÛPÆBtpÉçæænذìP'‘à{KÓÞÉŠ³ÄÒ+q‹±à»à»H$øžœ”÷],˜%–^‰Å‚ï‚ï"ÁwÁw±X0K,½ ¾ ¾ ¾‹ßßÅ‚Yb±ôJ,øž5ð=''G€U$ø.ø~X,˜%–^‰¥W#R$ø. ¾$ø.Ì‹¥Wbå}‰ßß¡v)’9 f‰¥Wbé•à»H$ø®¼ï­ƒ7íÙØëé_>3ì»\¹y—Ã' —UÌ’^I¯¤WÒ+Áw‘Hð]ð=ãxÒ¼‰ ÂùoÿÅ.Ÿò—ßüÎ7[°2‡Ò+±ôJz%ø. ¾ ¾ ¾Ë fI¯¤WÒ+±à»H$ø.ø.s(Ì’^I¯¤WÒ«‘)ºCá»H$ø.ø^q¦¼ ¼àÐ¥ƒÍl§æÊ‘½‡ö”¾z Q±Úºš$æðÈk‡wW調|¤ áuvUí¬¾PÕ¨dÙ©Ò$ V«<ðê+M™Ê³¼K£bÈ-bpZ;Ì’^I¯¤WÒ+å}ϺtéÒäzhÕªUUUUüq¬Ê‰'ÒÊÏ›7oÏž=uuu ?ñÈ‘#&¿iÓ¦F»WYY9eÊ”nݺýñÿñ¯ÿú¯“¤wïÞš8Á÷[H{StÍ!f¦ßð~ø'Èë}ûûß^ºn‰ üý?üÝŸóÏÿñŸþwX·Ã?wàÖO~ú»|ißæö?nïí`Þ|èÁÐÌLœ;±mû¶¿öï~ n÷Ú9†’´æpÛ|$½Á¿ù³¹pSÂ÷ZðÂó´àuyA^[±q¹uÆ:ð/ïYõÒʨÀ¨©#yÇntÃÆÓ[ÄþäÏÿ$ù˜À;* îyðŸã·~ƒºöÊãfVÉÝ‘Kz{ðbõ#ýëpQíþV ³¤WÒ+é•ôJð=;”òÆèá‡þüóϽJnnnÃòƒ ºzõj}O‹›Ø¿ÿ÷ÿþ‹/¾¨OìúõëcÇŽ­ï÷ÝwßåË—5}Yß•÷½ütÙ]ÿë®´zß³OO“éúðO­d{é¶h]l••÷ñ,—[ö¿”¶ßýƒß-9^lUðÐüâÉGCìPhÍx„Âó×Ìoô½&Ì™¶31öÄ€'ÒŠž>Úeúôœ’üõ°Xvs˜pL`z›ö-:wï|øÒ!“Y¾a™Z³Y³¤WÒ+é•ôJð=ûà;îí»¾NÀkWÜÞ_~ùe ¾#sÏW“ïÓ§OÚǽóÎ;.mݺ5­Ø'Ÿ|Ò©S'ñãƒ_ºtéСCñÁ[áøÃÏ>ûL3(øžmðý±g³ïùø#,ÚâMY›ÿ?ýVˆ§™_m]c—ÏìoµbF 7—ÿðÿÓLÚê—V±øËÒ¶ù¨ BVeΊÙnQç,–ÌX2Ýlah~öËŸå•äí9¸gÔ´QV‚[¨ê|C‹Ë˜“ÄçDŠ7Üu¬íò‚V¸µh‹»»\lÝÎ\dx_­~áÂ…ÜuêÒ¥KÚ^?Þ1:}ˆÞúôÓOq½ÛÝ~ýúiß³ ¾ó“moÍ’q´œXI~¾=š”]b*¢b˜4 ±‚vi>›Ÿ?ñó¨ -Û"²µCƒfˆªt™üW^®Ïöz¦W´5ÖpCoSÈ›ön21 ^4tÕÞ{f&ÓÖß¿÷£ïa/£ïn«Æîï3‡ïéh¶ÉÇä§=º˜Oά£÷„k{_ -usH›ûköµº-†Ò+é•ôJzuÇÂwÁw¨¸¸Ø¦M›Ö(|‡æÎkw‹ŠŠÂ»mÚ´áVûöíî&öî»ïÆdÞx㠻ŗnø°‘ .˜€$ˆß³¾Oy~rÌÁãüÐÏÿŸÝ2Ðw`_»ÜY¹ÃÃF­dÖÒ™Vâ Êü¸{È&V·Û§ø?¯x«U3cLìqæà Í!ucûº0-æâ²(XZ޲y€|E¸Íß·á¡^ Ú¶°õ;×™ NµXgzôê}w7‡{îv™$c‚É´KÖßc˜»rŽÝZ³euÔNY0% 2„´˜^I¯¤WÒ+éÕˆ ¾ß^øîá.O?ýtøž““cwÙÆ»U[[k·Ø˾UûŸ˜pÞíÖâÅ‹ëëö„ LæðáÚDÁ÷ìïO<×'j„ÒúXæ² l»]7(êãÁ8y’ÎŒ®¨>Ðí~~ÜY~õ6}ñ—¨ÓØã†NšC§;œb+­îßbW–¯ä²ƒ*VG¦”ÍLÑ$hüÏÊl¤…ݱZX…ÐÓó g?þ—ó?YŸ±ˆQæÑQaì.^+Ò#Xx¨ž-nႲKžEÚ‡´ÌÊu½æ0Á˜x a©õ=‚uó¬€YÒ+é•ôJz•ýð]ð½cÇŽOD¨gÏž£=Ü%yâȇz(|P~~¾Ýõ¬í^ÂFU#•¤§†Ôì¾ßqðÝm^xJˆíU‚üØŽÒ“¥V‚S kçvÔºñë¿q÷†ØV3ÜKV‹¥[2<Ä’$8[š…0–Ô—=å32i£3cÏ¥3fiœé›G»FWƱI.ãF”꤀°Ëôæ0Á˜øÝûÿï}áá,<&¼µµÃ,é•ôJz%½|WÞ÷»ï¾ßyZøþï¿¢0/;2ÑYP xšr¤nInM,c-p<“fGðýŽƒïnðÅNÑcM9\æ,[{5çÇPÂ+6­ˆÆž:{²·çؽ;±³ýìq¡9?{|T’xPOÑ$FÖw¤Åš¥O˜¯•Ǫ¨êö/½9L6&°};‚qÀ螯­µÀ,é•ôJz%½|—÷½O„ð¾{*w»‹pñïo¾ùfII Á6aê÷·ß~ÛSÅo‰y!­¼¼¼Ü…÷w—rÉkvß[|Ÿ¼ý)~òª.•7ùüB¶IÙïuζµŠ÷ÅzÅÏtZkþv»i…ħºoŒöîýpÔ/ÅY€v9dü`Ï®€Aj 2¹Í–p~!¾´ÝÀ{‘±ØêŸ4íMQÓên>¸Œ_½¼š›óÓÉÖ%KA¥g†>ÖcD&„˜È•û®œì(;mÛ=Í«äôO?¹—UÔâR2ë2pÌ@·X&@o“¼Ôîê]¶iÌɪ{¢b·ˆ11÷ìðgy—ØÒ¶‰&cR;;Ppbwã.å[Þºæ3*b Y WÒ+é•ôJz•áð]𽰰ЈuIß;wîÍyäÈ»$Y{(Z~ìØ1OCédþøeï,Ûh¶(¼”dYBþ%d)~ff4„™ÁÌ fÉ(43$–ÃÌ<ï”ç/U˜A#_ð@÷½Ç}¯%MçéÓ§оg-]é6­€’oÀ6+ò ÚL'ÈÓÄW_!|žï íä#‘ˆ^˜¯©©47£Ú÷_È_S?†·¯J‹`žsqxÄ;=+RêeÙ@f02侯¾BøŠö€öÝšËGqû-…Ûlÿñ 4N·J€”t¥^ Œ·É}_!|…ðí;í»e—s[eÉÑ[E…˜>Rº•ôÙ8_!|…¬ï+ÚwÚwk.Žîse<ߺ7‘Žæv@J±mf\©7>_!|•ÍÂW´ï´ï´ï"8Ø`®Ûíÿ«ï,ÎÕJ€”\¥ØÌµ’nü8ø á+d5_m˜ÂÚí;í;í»¸ñ`²´ý VIóÿ8 {r«ðÔ—Gi5ó«D+ÝÆgÀW_Y@øÊ:mí;í» ãÐ9ѺǽÜ\4K¢Gº®vPH¬®®«J¥™S%W)6> ¾BøÊJÂW´ï´ï|¿|ýÂÙSf®žy®%ŽžJ*Šu¥ô)‰f6•V%_!|…rÐW´ï´ï|OÜ>Ûœ÷÷K ž•Õ©s<%f!)YJ™gfP©TBñÂW_Ѿ˜Ð¾ç,ícþ}ÞUæ’*m) :(6Ù,%èlKA&eJŸ’ˆ¯¾BøŠöýmhßsœ¾«‰’öƒo­°«k;.¤&ãÔžì‘Ò¡¤(5™4)eJ¾zO_!|µ~ ê>í{îsçÑ MæA±Í ÿ8׺78ä¢ýY)çZö*f^ ÝË”¦Û®ã+„¯ð¾úE- о3Maü!z®ÄŠÚög^5Ùï[[?rþ΀p…]ÁÏ$¢¨m_ÏdÔ°,ø _á+|Eû@ûξᅴ¯zûª \K3Ëñ6ÛODvÖuµŽ‡E@ ¬Â« +Ô™°¸–xz+•Ãêà+|…¯ðUî´ïYÀàõNíðu$°1³@KîeÚ¸újS“ ÊØHTL…ôí nrõ” ]ï2¬¾ÂWø _оg÷žÜJ\ WÆç9½½p l¬Hœ »¿¾ …KA;ôn“‘ç\\?ž¼¹÷ä¶aAð¾ÂWø €ö=k· 6fvb6µ¹áŸÚj@»¹i‹_߀->ÑNÙ3¥Pøm5©s ŽB¤@½7…QÁLßå _á«_á« S }·Ï^>Õv`¶®¢ƒ~ó¡¥w´Ë±ðhhKIôˆ½§¢iÔß}µk:?MS“Õ”5qM_Aø02 —‚Öw5ùüåSð¾ÂWøÊÒ5hßýSVãùËgz•+>ÔB¦i÷.Ç‚ËÀ^ïª3ÍÕ©³îþºÈˆ76Ñfõâ§)h"šŽ&¥©i‚k œiÞmï*Ž_ )D/^=3_á+|…¯hß² Úw¸ûøfÿµTh°¡"vô ÃGµÛ¹H;Žˆì¸Øv 2yÚÖ]¦÷²[Æ‚Ét< ž†¡ÁhH˜†§Aj¨°†ý©i²ñ£z‹yàZJA0_á+|…¯,×¾í;¼|õ"}wTÏ“9ºKŠÛ mÑ.c*ŸÑÖÆk‹=2uº)ïBÛþâèá²ØñÊÄ©êÔ9íYÖØ]æè©t÷ÕzCŽð°§y4 íÌ¢—[éhÇd¢ûj§¤ßèúKý“Ða:X§h ÞØ]ªK邺¬.®[èFºnª[kŸ¡öª;®7ÜÛhRšš&øâÕsÊà+|øÊú$“Iî3f¿ }‡×o^kã‚ô‘¾+‰ö1Ÿ6o®Iž:ßRxÈ¿~§}¾êÍ×NÇ| FCÒÀ4< RCÕ{ʶo@Ö€¯_á+¿ß¯Â={ölhßÿ|>õÖ£kc·ú;Ó­Ññ@ˈ;gΜ™3gÙíû¬Y³tkÞþ³@û^XX¨[Ï;×ÈRþÏÞ‚ªÅ>½löb·,Ú¶^ìiö²ž´§U‹;+v^DXOv‹„ód—ï1yØ<÷ú}áraÿp¯aû1wÎ@¾ÿµø& ¿Dà¿n·[ÞËÒÕº®Ý€€/šÓéôï,äûår‘ïêWÖ€|q€W¶kKà† ß€×6{Ȳlüø; ߀´V¬†Áh«e@¾§Øív«Õ*Žòý½ú¾/Šâñ3&äûXY–!„<ÏÓ+xï£Çû‹ÅWÁ·mÓ¶eäûHÓ4aPUU€ ÷ªªòmÛ†‘¢(î÷ûwû¿ÌÈw òØl6ap>Ÿã3ûýþqt2™\¯×82›ÍGÿõ›;€ˆ4ˆâ>%$ @¢i£ @$ˆ%@"$  €K@,‰ˆU0÷ì¸Ô©ì\„»ßO¾¼ÏÇßóf766âùáᡯ¬¬”¦7¶··s߈ì©+B|þH§Óggg9|4zŸŸŸÏïÝßß§®øC“oooÓGNOO3ˆï@ï–——SJ;;;ù{{{q`uu5‡žGï1tç1€Ï]ECFFF¢F-º×@|z©=¥ >¢Õj¥®›››ÞGïaff&þëï™ßÖÖÖ¢'cccQ¢†………——— â;ðÍ•÷Pî^ïïïWÞË¥ÕF£‘y£Ýn—¹{©¯šÍfñøÎÊ{899‰SSS1®½»´ú¹èöñ½¯¯/j´:ÿ5ßÁÊûÃÃÃððpœ9??¯½}i•ÍÍÍhÎÄÄDÔÒá¢ÕjeßÚ•÷¢ÙlÆ™õõõjFï__Zåññqtt4ZT꫹¹¹N§“@|jWÞËòzh·Û£÷Þ.­rqq‘Š÷+4[[[Äw jå=,..–åõšÑ»K«vww£Q“““Q‡††¢ö÷÷G=>>Î=ñ¬¼‡ƒƒƒ8³´´”CÅèÝ¥Õ ÏÏÏF#z5==ýú{ðÅõõuîˆï`åýîî.u]^^ÖŽÞ]Z­ruu•B™¾¿1;;ûôô”@|‡Rú/‘@|ññ€%¾ƒoÄwæðÆøñðuxã ¾ƒ0‡7ÀßÁÇùKW¯^žð˜‘‘¡§§'&&æêêZ^^¾dÉ’Gö΀C™ ãïèúWB€”@„ D (P‰)(*HA JQ„¤ªîq7ÎŒ[é8ðüÀݳÏìl±üv¬f¹ÔšF#óÉ~¿·ØìI:ÃáPÛ¤) º\.L‰ü~.—;Úðñxœ1Èf³Ífs±X<ÕTL§StLŠÅb¯×[¯×ÏX­V™¨Õj£ÑèíßgÄ×(ç9NÔ÷_A!„úNoÎ|>/¡‰ÍfkµZßËétZU«UjÀË¥3 $ÙívGB“R©„Ž¢P( ´¸¤J¥¢ÊB½^ÿgI<¿^¯OKúý>šÖóù,ý×Á#„ ßl6Ô÷7!„B}'„7'Œ6‰H°.F±(Âê¸Ê‰Äív“!óù\Bè¸$ÇãQ v»ý~¿Kèóù$t:Øcµ\.§R)¯×«¦èt:¦¾ãþáp8(Âá06"5õMœVÀßp}5ŸôE}Ç\«ÐÎãv»/— õBÈ_C}'„7g,“ñ6K·ÛÕšXÇ!s­:+áv»U¡iÒtM^ñB޽¢Ýn+c6õ}6›iè+“N&“椓É䃽3€´b £pä!… !‚‚T("I‰(Š—ÔUPª¸‘JÐ+Q®z%Uñ)¨R*âDIè},-cö9Ûtzžs¯õá:÷?{ffæškíÖÿïÒŠÃÕ)m_OÀ[¾s”fÜó–yóæiÀ½{÷"ßC!ü¯D¾‡‡)i;Šee%!míkYO½âœ±øÆ¶®H_Ûɺuëôí§OŸ*òݼ~ýš¼¾ôz½º|oíðöíÛCËwÀ ¤‡ê;s¼ïRwùδäýû÷Þph˜½{÷ŽZ‚)øÿ0„Bä{y8÷îÝ«Ïããã•ñ–ã/^TäãÇŠPá:È9³xñb©ˆUМ&7nÜÀ$”ŸÖå»ñ€}ûöu‘ï.\зÈèß‘ï¾ð;v4ã¯^½b¢Is!|;~YQ‘ï|Þµk—Þ ˆùóçã\²)hýúõÜ–¾&¥åË—óÕ¦M›ôë“'OV¬Xáý°O¾úüùóÔùB!ò=„<œˆEÉÍz-&md´Éž={JMßjêb}âÄ ‘¤ ŽÕ]ãå»' ¨ØŠ|wNzõêÕúöÇ¿#ß?~¬®ÙN§éŒ7›7oöÅ–òW ºÿ%œ­ÆP$ þEר85ÇêÔÚƒ_˜ðvb*ü? !„ùBNÚ/º\µ>þëׯ¹fÍiGӔ饬·­ÅrÓF’ñ¤Ãé¥8´|UÖbFoÉ÷óçÏÿóä8»Bâ7½øCËwÚJò¶Að¨(ÈìÅZybb‚bf;t§±;|?räˆoà—/_¸ÉwîÜ¡(VAÒù®ö~ ïûö­2ñʸc úþý;{;s挜œæÌ3—,Y2þ†Bˆ|!çÓ§OÝ’`\ݶ³tm+m }åÊ•¾ÙkÒÆÌ`ìù~ðàÁ/É÷7’ïüÄO*lºïûÒ¥KuD`ÖaS"æêÕ«î|ß’ïöáT–Ý Ú5 CŽ"äæa¼mîÍY„'Wüd‡nìƒoGI}>—Æ¡B!ò}’òp¢í:fß©¤ÔÈ 64ã4OTüرcvÎt1Ó³\ëõë×±²XÊK}Ê Ò=û®­êÞwÜ,˜Rlz¡õ{Çì;# ·¨Ùúݵ¤Ì[\Â; \­{îܹR¾ºÄ°ÕÎ;™ZÈdùîå®ìüi-›åF=Ô$´^hà âÂ[ñ•+Wþ!„"ß')!§³¶ÓúøgÏžµÚ¼8÷Œ©Ãîy;gê¹l¦N>[y§±{÷î… Z¯óÙŸrÃB!ò=„Q‡n†~:ì«Þ¶mÛ ñxl”ÖÅþî~äæùóçÚ‚[ÎòñèžMI6×½õì¡£|wstGùÎÎmZ¾ß¼ySh¼£æú#~é8âÜàÛ·o¥|§EŒ~¥ÿŒ7q H‹ìVçRìš/ñaÿ¾½åÑ£G/Wçf/^¼Ð‡éÓ§ósΜ9îõB!D¾‡0ÒX¯ƒ$¦ªœ={¶¯vÇç­^‡È¸5Ь–˜åŽ"[v_éìZÌt‘ïäªËE£êò7ú–yÂïô}w |_*⥚Z+R¡Ë]×[Ê÷Ó§O7 R ö¡R¾vvøBkÑ(Ï(´è•Áñ¯85ÁMgÐöíÛµžTû|Ø,~ua1þ™KP«¸“÷³fͲ½Þ¦£%„Bä{aÑ¢EZ ´õtH–¤› .+md<²RëuOVx'ì› 5å{?³‘rµ×:ããã6ö 'ß©ÕërÄ7æuŸe¸6µsWÝK§%ß‘Ô~ïÁVÔþúå[)¨V3–ãDÜd³,NðæÜgœEÚ‰»‚êóܹs§ùF™B‘ï!ÄòŽ‚ïût`¶UÚÈÈ~üøq«Hsg¾4 ¤Ò­A›pè–WÄyèRµ3C@…3gè²,”44òs¿3ÖÈÖ×ë;éZã=»B—¹´Ù²e ¶™Òââ~Ž˜|,ô²›6‘¼©àœõk©Ñø7š 8×Þ„×zÑáˆ^§Ì˜1ƒŸ³gÏöìb !„ùB,ïd¬+OE–A²Þ>ýU›–Èÿ!·7ÎÇÓQqbbÂ}`&;½^v4\ÔåË—;^Þ!æÜpP"Á›/4p®+O_Ni8ƒMÞ¼yƒß‰—œ-hšõ©le,X V~.[¶ìG!„ùÂhZÞñ“÷éؼÆÖ¯âüœ9sæ¿ìÝqÍõ÷ÇqP@Kb,€¬ Ö"ÀbSAL¡Ê‚QÙÍ(ebdÚ”ÖÐn’v—* Æî`HÚY«ÔX3µ’ÚÌì¦ñþ½æwfî|ÿùúÖgÝϽw÷ùøã3gkïýç¾Íœ=÷œó®S§Ž‚zõêY…Þ…!é;@Ë;ÿ:"‘:p4L¬‚º}j¶ òß²×vëÖÍnöèÑCÏ}]à €ô åJË1yvbb¢ó$ðsæÌ±ý36,­gÆ ]X¾´¼ó¯#¢Ó÷Ñ£Gk°µŒé»,Y²Ä‚N:éÙ¢E =GŒá €ô å‘H#­*ÛBwÏ7jéÙªU+]« 66¶J•* êׯ¯çòåË]ø¾´¼Tª ~È! fΜٽ{w¶-Ô’xIOOwa@úÐòNúNúž——WµjU»ÎIO‰×³yóæV†‹=žÒw€–÷ÛÓ¢wý~Ë–-µ‰Üý/<ð€~Y· ¹ÿ.33S¿sÿý÷»0}ÖvsÓÊ•+mnµC‡;YÕjï¡EúÐò~{ºßÇ®ùLKKsÿË;ï¼£ßTÿOîa}ùå—]øÁ„ ôé$%%?>°…FìNÜ¥K—:@‘¾´¼ßÞŒ3,™S|GJﺊ_¿# \ø>WMNNVõ]ABB‚žµjÕÒSöìÙã¡EúÐò~›.)((¸S¥wÝõk*À»p…÷ß_ŸQåÊ•_ýu2tèP=Ûµkg²^¸pÁ é;@Ë»téÒÅV Þ©Ò»¨å]¿öé§Ÿ:„1ퟱå3Ï>û¬‚Î;k§¤‚Ž;Úw€ðAúÐò.ê°»ô{/½3´™Š‹‹[·nm-4Ös5vìX=¥qãÆz>÷Üs&HßZÞÏ;§—HVV–÷Ò;C«‘lÿþý¿ú,˜4i’ž÷ÝwŸž²k×.9Òw€–wILLÔ«fÍšå½ôÎÐjä[¸p¡>/ÝâdMðJÜíj§N:é©•DçÏŸw€Ð"}hyß¹s§M(^¾|Ù{é¡ÕrÁn`]´h‘¶Ùêw[GcsqqqB¤ï-ï%%%vËææÍ›½—ÞZ-/Ž9b§è½÷Þ‹ŽŽV0mÚ4=%&&FOUèÿ¤ï-ïFÙX`µˆ÷Ò;C«åÈêÕ«õÙµiÓÆ¾–‘)S¦ÒwÑwþ¾´¼çääèU’››ë½ôÎÐj¹o³ ,Pеk×AƒÙ³òóóŸ¤ï-̽—ÞZ-Ξ=«[œ¬ÐÞ³gO“'O®Y³¦ûqÀ€Î7Òw€–wÙ´i“^Õ²eËÒÒRï¥w†VË© 6ØòM/(¹sçZ`7:é‚'çé;@Ë{QQQTT”^øÁx(½W„¡UØ:щ'®_¿^AýúõüqíÛ·×SvìØá‚ @úÐò¸$_Ë{(½W„¡U\ºtIëDõiꋚ &(HHHèÑ£‡‚þýûëY£F¼¼<TÒw€–w˰¥  ÀCé½â ­Bõu}šU«V=|øp£F?õÔSz2ø~ýú¹à¾´¼‹]Á“’’â¡ô^цV1cÆ } C‡ÍÈÈP ¶l´zõêíÚµ³„Þ|@ú^–wINNÖ »uëæþ1»3_¥÷ 8´Š?þøCóÍöŠ%îúóOMðè)©©©àÒ÷Š´¼Ÿ;wN/”¬¬,¥÷Š9´Š}ûöÙ±9vìX¯^½ìïÆ:Ø…_zÞu×]ß|óø€ô½â-ï¶KÄ®ãñPz¯ÈC«°û›4·zòäI²råJ 쎧޽{;€Hß+Ðò®‘zaݺu/_¾ì¡ô^Á‡V¡»Wõù.^¼ø7ÞP ¥4Ë–-³Ýð±±± æÍ›ç> }¯@Ë{III‹-ôÚÍ›7{(½3´ -Ÿ±X_³Lš4IÁèÑ£m¡dß¾}õ”íÛ·;€HßË7Ðò.‹-²>ÅÞJï ­âÅ_ԧܶmÛÂÂÂ&Mš(^±bELLŒ¥òzV©RåôéÓàÒ÷r ´¼çääØksssËRzghqqqú çÌ™óÑG)µk×Z0|øp={öìé> }/¯@Ë» 4H¯U¾Œ¥w†VqæÌ;Šiiiö•΃>hc¬Í›7ïܹ³‚'žxÂ|@ú^þ€–wÑ÷z­Vw—–––½ôÎÐ*ltµaÆ?ÿüsŸ>}?ùä“*½ÛíNÞÿξ“¾ƒ–w-™‰ŠŠÒ˵væN•ÞZŸqãô‰k€5ð½Ðúõëï½÷^6Ì*Z1éþ!}| å]fΜ©×&%%)¾S¥w†VqñâEm ÕçþÖ[omذA~|óÍ7ÈØ±cõìÞ½û­[·À'¤ï‘´¼ëjU{¹.[½³¥w†V‘ššj÷­æçç[÷Ô¨Q£.\¨ cÇŽÖî5{öl }'}-ïÿêž”””`”ÞZÅôéÓõé6ìÊ•+M›6µù‡þýû+HHHÐI[¶lq@úøÚò.ÉÉÉz¹2xÅÁ(½3´Šk×®iÛŒÀš5köîÝ«@t„T’W0uêT=åøñã.ÒHß_[ÞÕ-c/WÿLðJï ­Â²v»R`ñâÅ t„¶mÛ¦@ìrÖ.]ºÜ¼yÓEé;à_Ë»$&&êåš[ jé¡UÁ3Ï<£cЫW/Å}ûöµ½ïöÝ‘þcïÞ½ow¤ï¤ï å];"mˆ¶F¯ôÎÐ*춦¥K—ž:uJìØ±ÃF/}ôQë¥ÑýÎÒw Ì[Þu7S‹-,[ jé¡U|õÕW: ’½qãF÷ÜsOzzº™3gŽ999ÎHßIßAË»±{ìããã{+½3´ V­Z¥óо}û’’UÜ1ÂVÂ×®]ÛÆXuÆô¾“¾ƒ–wU7eNï¥w†VáÉÀ­ñýêÕ«111еþhòäÉö÷d¿~ýhפ¾“¾ƒ–w£$Iï ¼÷Ò;C«ðê믿֩]»víÛ·Ïb5YµmÛVÁ¬Y³jÔ¨¡@%yç?é;V-ï¢fw½ƒß­?Á{é¡Uxµ~ýzŒèèhM/Y²Än`UC¼±5rôèQç?é;>-ïÊ–¢¢¢ôZ;ìÒ»²v†Vñßè¾UGyD±n`µÑUûºFi½jð–Ó߸qÃù@ú„CË»h¯¶ÞAëÞ—½ôÎÐ*<ûñǵvF'dëÖ­všwß}wܸq ”Ü0Àîduþ¾áÐò®«Uíë²Õ ”ÞZ…—¿ «W¯^PP`=]uêÔ9vìX£F¬…¦V­Z Ôiãü }BÛò.ºǶ|£ôÎÐ*<˜6mšíŽTüØc)>|øÞ½{ØO>|Øù@ú„ªå]RRRôÊà£ôÎÐ*<øý÷ß›5k¦£²víÚß~û­yóæŠW¯^½lÙ2mÚ´™?¾MP;ÿHß´¼«[&°ž/x¥w†VáAFF†ÎãÇòÉ'ùå—C† Q ’|\\œÎÒwÿ–wIJJÒ›hn5Ø¥w†VáÁÓO?­Ó§OÅÖ0›——g³­ªÄ[ðÚk¯9ŸHßýZÞµ#RoR·n]m vé¡UxpëÖ-û+ñùçŸ×=ôâÙ³gïܹS¼ôÒK:tÈù@úî?Ðò^ZZªšô&ÚìáOé¡Ux n;í¾û ´¼‹ŠîzàËXz÷gh8uê”ÎìÞ½[;%[¶liﺙUAµjÕÖ­[§@>ÿüs }"½å]¬ý@ï%%%e)½û9´ h½ŒŽ.^½råŠ}™#_|ñ…ö&)èׯŸ­¦iݺµöÄ; }"½å]Kf´jF3e,½û<´ Œ3&°èÝîoÒ@Åõë×u /X°@5 &Nœè €ôˆè–w±Rebb¢â²”ÞýZ~øá‡Úµkþˆ8p ÝZpäȲaÆúõë+X³fé;Ñ-ïYYYv˜uÙjÙKïþ­Û·o×qªY³¦6Ïœ={¶jÕªö÷¤Zkìë “8é;¹-ïÒµkW½OrrrJï> ­¶yfäÈ‘Š·lÙbÙüùóçí¤ 6lùòå6Ý¡.y }"±å]RRRô>Êà¡ôîÓÐ*põêÕ¦M›êP½úê«úqêÔ©Š‡ª‰UÛH£=ñÇ4‰HßÈky/((°cœ™™„Ò»¯C«@zzºç'Nè²ÕV­Z)~á…²³³ØAmذ¡ýÕê¤ï@dµ¼KRR’ ùùPz÷ah˜?¾í‹T¬?JËgŸ}¦eð TžOMMU ùpÒw ‚ZÞÓÒÒô>QQQEEE>”Þ}ZþþûïŽ;ꀩÓ]?êi‡íÆ£F²ÎuÑ(hÖ¬™ö¥:é;-便¥Ö¼iÓ&Jï¾ ­º`õ?oZ‹‹S=ð½–òøÕ«W+ˆŽŽ¾té’¾áÐò.ݺuÓ»%''û_zgh!4yòd½Ñ£G+ÎËË»ûî»õ£Òú'N(õÒŒ?^ÁÈ‘#€ôyË»¤¤¤èݺt風ÇÒ{è‡V®j½ŒNàºuëõx%ñúJ×–)Ö$ëÑ£Gcbbkg¼¾¡my/((°ãš™™é{é=ôC«@`Ë»õ¡©yF±i;%˜­@222€ôUË»$%%Ù½ñþ—ÞZE˜°YÕþýû+...Ök¥J•4̪1VëìÒNö%Uƒ .^¼è¤ï ZÞÓÒÒ*UªUTT‚Ò;C«áýõWll¬¥ìúñÀ•þŸŠî‡ Üñdë6Ìþ½û®ªÀ÷8þ“izK¤Ä¥ ¡ lCW: é½÷.½]ЧH,°²1H“Ð ½3°°¡·íø*ÛûÎ3™çÛ»˜Dι÷|¿ó›™s3ÞŒž÷v÷ãážsá»Ú™ÜÙWcÛºv,QJÒ „úùù=qÑÑ’F%&äὕ£"%ÍjÑ,È_ówzè½1úCŸï¹¦]$•~´Ü²¡ïtn•*)²dÔ¤žóŸˆ.#©]R'N‘+û»Ÿ#‚ïð¾³nñ5$Õ/S:?¿ÄÔ.)6::ï5µK2ÁÛ±×øßÙSUëHjR»•7¬ÙXR'Mž(§W; çy‚ïDßáûΜòÃXÖúur:ðî;ùù=µ«W—´vú´<¼7ù;ß‘4sÈ öÀwwù~ûâ/ü¼½[³Ï‘œ7cÑé¬ åËU4rð˜ñ#'IЉyôàÎcío†ùïDð¾ÃwÖ¦q¢¤á/¿”Ÿ_bj—d‚ÏÃ{¯ïÜ!§;wÀwøîÍ-˜¹XR‘"Evràí×Óä´~íÏ·ë ©e³Vœ"øNDðýaßÙŠ‰ã%U­PþŽqëÒû¬!ƒ%uûÎwì¾ÃwÏ®{çIM7·ãaFJª\±òÁÌã±Ub% è3˜S߉¾½ÁwvgÏ®˜ÈHIïΙíÖ¥w[|l¬¤Œ•Ëá;|÷ò~rêú“±Õ$ é?Ü^>Ó¢µ¤öÏvüðíä´zñÎ|'"øþ5ßY¯Î$ulÛÆŽÝºô¾yårI5ccí¾Ãwï½·6Êiýšf‹ŽŠ–4eìôI£§JŠŠŒ:°ãg ¾|ÿZ‚ïlËê•r:—¾ÉÅKïÁoZ…ïðÝk>h”¤*•«^<~eÕ¢ÈiSÚæÏu’Ô,©§¾|ÿZ‚ï¬á7ž’4}à/½¿i¾Ãwo®eÓV’ºvH¶ã>=ûIНñÔÙíé×k§¾|/àà;›9x¤úññvìâ¥÷à7­ÂwøîÍíÛv°Dñ’æN_`/KêÑå…ëÒå´ráœ%øNDð½À‚ïì|Fºœ6¯\áâ¥÷à7­Âwøîå-œ½TRáÂ…wmÞŸ™±¯Há"ÍÛçà%E”Š0âs–à;Á÷‚ ¾³Îßú¦¤ž;º{é=øM«ð¾{|=º¾ ©IbS;^0k±¤GôÈŽíîܾkÎÏ|'"øžßà;K›;GRTDÄ­]™î^z~Ó*|‡ï_öéÕâªKÜw˜½LM~IRÃúOÛó%«W«!É>ÏY‚ïDßó|g÷O‹­XQÒ²ñã\¸ôä¦Õä;|güûå´îïÝ8ÿÓZOÕ–Ôë¥>›Ò2ä´lþ*Î|'"øž÷à;ÙóIÏ4jdÇî^z~Ó*|‡ï¡²‘ƒÇHª\©Ê…c—?þ`«œ–/X=mÂ,I%J”سå3Î|'"øž—à;ËZÿ®œ¬{ÇÝKïÁoZ…ïð=´Öªù3’ì#ïvljܺz`Çᮓ%5~:‰S߉¾ç%øÎÚ4n,iøË/¹~é=øM«ð¾‡Ööo?T²DIIs¦Î·—¾×ER‹¦-/Ÿ¹iσ—ôý—ûp–à;Á÷¯|g+&NT¥|ùÿ9vÄõKï97­†ßá;[ôÚ2I<òˆ=DòÇÇ.ÇV‰snišþþ9-™»‚³߉¾?hðÝݳ+&*JÒº×f»pé=ÈM«áÂwøÎRº½()©Q;~ÿ­rzk庙“^“T¬h1“=g ¾| à;û~çN’:¶mcÇ.\zrÓj¸ð¾³+gnž9èÕ¡ör̰ñ’Ê”.{òÀ¹îS$=Ý0‘³߉¼|‡ïöFO-iÛªBd„¤7¿û­üÿ¶¸èhI£òü*GEJšÕ¢ÙÃ=Ðß¾Û}µáÝ'IªðD¥‰¯Ìµ—õ«?-©~õF«F¤U*SURë†ßõÂß'û;Á÷à*THÒ_ÿúWøÎÜÚŽnzÖ©•ÿßcj—çß`j—d‚·cøßÃoí›'¯‘8žÛÿõèR1’:¶ì1öÅ™rz¹]?ô ߉(xÆfIFh×ø^¬X1Iüã}Åw;ðì˜ ŸzÏÇM«ù|w‹ï|ðæÍïÈɾàiö”y’ .üiúž oa|ð†ˆŒÍ’ŒÐ®ñ=""BÒo~óøÎ\Ÿ ŸzrÓ*|‡ï>˜}^RlÕ¸‹'®¦tM•Ô°^Œ†ïD$c³$#´k|üñÇ%}þùçðùôÒ{›Vá;|÷Áš7i)©Óó]oœÿioÔ•ôrJON |ÿg‘±Y’Ú5¾WªTIÒÝ»wá;óï¥÷ ß´ ßỾשT©R’¦Oœ½eã§rš?s1g¾ÿ¿‘±Y’Ú5¾ÇÇÇKÊÎΆïÌÏ—Þ3rÓ*|‡ï>Û²ù«ä”ñá¶¹Ó¾ãiÛ¦LÎ |ÿrDdl–d„vï5’têÔ)øÎü|é=ç¦Uøßý¹^/ö–Tûun^øYj÷—%Õ«Ó€Óß¿›%¡]ã{Û¶m%íÝ»¾3ß^z~Ó*|‡ï>™Ý´*éÅî/Ûq½:õsŽ|'¢Ü›%¡]ã{—.]$¥§§ÃwæÛKïÁoZ…ïðÝ'Û¾i—œÎZbŸœ±ÏÏH²ÏÒpfà;åÎØ,Éíßûôé#éÍ7ß„ïÌŸ—ÞsnZݼr9|‡ï>ßœi $)Rd׿ýv÷ªœ¶üðSÎ |'¢œŒÍ’ŒÐ®ñ}üøñ’æÎ ß}2.½¹i¾ÃwÖ½KФĄ$;¶'HJªS«®=S’3߉(±Y’Ú5¾/Y²DÒˆ#à»OÆ¥÷ 7­ÂwøÎ®œ½U³z¼¤Wÿ­¿½là| >¥Û‹vÌà;YÆfIFh×øþþûïKJMM…ïþ—ރܴ ßá;ûh}†œV/^óiúžÂ… Kš=eg¾‘el–d„vï›g[·n ß}1.½¹i¾û€ï—N^;”yüÚ¹;ÁùÎ&™&)&:æÐ®ã g/•Óæ·qfà;›óÿØFåÿÉó5jԀラÞ]¸iÕ}¾Ã÷~:iôÔjqÕôE ê6 þ^ö|»’Z·hcÇ=S¿/©V|íÀ¿ù0?óˆŒÍ’ŒÐ®ñý7¿ù¤âÅ‹ÃwŒKï.Ü´ê:ßáû¥WÍ úRÁßËξT©beIÃŽ´—O7h$©{çÎŒÏùNDÆfIFh×øn•-[VÒÏ~ö3øî§qé=ç¦ÕÁáÍwø>bÐh9 è3øèžSWÏÞÞ¼a{bBãù^öîš÷åôÎïefì+Z´˜¤™“^ãÌø–ïDd`–dx¶c7ùž””$éСCðÝãÒ» 7­ºÈwø~bÿY9¥&¿”ûççfç~/ þ/?ÊWßáûú5ÈiùüÕ¹~ýü]øžÏ5Il*©sû®ÐÙ'|'"£²$c³»Ï÷N:IÚ°aCØó¾³œoZ…ï~à»}ߪ}W¨¤ˆˆÈO6îüðæ…Ÿõèš ßó¹}Û–*!Éþˆ=ûïDdT–dlöß§M›&i„ áÆwøÎ‚|Ó*|÷ßm­ÏÐÕ­]¯UóÖFyIð=ÿ[¹ðu9m\—ÎÙ{¾‘QY’±Ù|ÏÈÈÔ®];øß¹i5ÌøßmÛ7íªZ9V¹*(¾³¾½Hz2®ÚÅãW8áÍw"2*K26{‚ï·oß–Tºtiøß¹i5üøßvß³å³Õ‹×,›·Ê4Ÿ}úFAñ5Kj.©ãs9áÍw"2*K26{‚ïV¥J•$eggÃwøÎM«ð=Tr‹à¹ßËì8%iÒ詜på;’%˜íØ+|ïÒ¥KžBß7­ÂwøÎì5äôáÛq6Â’ïDdH–d`öß,X iàÀ_õðqÓ*|‡ïl@ïA’b«Ä?šÍÙ?¾‘!Y’ÙC|ÏÊÊÊów¯ÂwÆM«ð¾³M[Iz¾]NE¸òˆï[50{ˆïýë_‹+&éÞ½{_õ½ðqÓ*|‡ïìàÎc1Ñ1’ÆœÌÙ'¾‘ñX’QÙÀì!¾[ßúÖ·$¥§§ÃwøÎM«ðýÿß/¼v(óøµsw‚½D.}SN￵‘³6|'"ã±$£²{‹ï³fÍ’4tèPøß¹i¾Ã÷œïmµªT‹«¦/jP·a÷²A¯•T¥R•s‡/r6ƒïDd<–dTö߯S§|‡ïÜ´ ß-ø~éÄÕÖ-ÚèK/{¦ykIÏ}çyNExðˆŒÇ’ŒÊžã»#éÆð¾sÓ*|‡ï#–Ó€>ƒî9uõìíͶ'&4þ^vx÷‰Ç{\ÒØá8¡Îw"2K2$Û±ùÞ­[7Ik×®…ïð›Vá»Ïù~bÿY9¥&¿”ûçö`Äù^¶vÅÛrZ¿–Ú|'"ƒ±$C²GùøûëÚµ+|‡ïÜ´ ß}Î÷•‹ÞÓÞ­Yy¸rφô.©b…J§^àl„.߉È`,ÉìQ¾ß¾}[RÉ’%í±8ð½ ßË\X­'—4«E3NÅ—œþð}ôÐq’žx¼t?tÒ?«ódIÏ5íbÇž B"2Œ%’=Êw+))IÒ–-[ƒïð-kûLÞßá{r§çÌÀ÷Óòù«sÿüúù»ðùïDdÎùN$¯ó}Ê”)’ú÷ïßá;ƒï¾å»}ßj­øÚ’"""?Ù¸#ðÛ~Ö£k*|g~à;†%ŒC€ïÏÏ”.]Ú·|‡ï ¾ÃwÛGë3ôEuk×kÕ¼µQ^’øÎà;†%ŒC€ïV£F$}üñǾå;|gð¾Û¶oÚUµr¬rå¾3øNDÆ`IFb; ¾/X°@RJJŠŸùß|‡ï»ïÙòÙêÅk–Í[ešÏ>}¾3øNöƒ%‰C†ïïo²>ÿüóðã;|g ¾{õ½îÁw"2ËÉH2|·Ú·o/iÅŠþá;|gð¾Ãw߉È,É0lÇ¡Ä÷ 6HJLLôßá;ƒïð¾3øND`I†áã»U¾|yIYYY~à;|gð¾Ãw߉Èè+ÉlÇ¡Ç÷ñãÇKêÝ»·øß|‡ïðÁw"2úJ2‡$ß³³³åtïÞ=øß|Ï[ðýÒÉk‡2_;w¾3øNäñ ½r2‡$ß­N:Iš;w.|‡ï ¾¥à»}oë¤ÑS«ÅUÓ5¨Û¾3øNäå ½’ Àvª|ß¶m›¤¸¸8øß|ðàû¥W[·h£/ß|'òr†^Ià滕 )-- ¾Ãwß0ø>bÐh9 è3øèžSWÏÞÞ¼a{bBcøÎà;‘g3îJ2úÚqhó}íÚµ’š6m ßá;ƒï|?±ÿ¬œR“_ÊýóóG³á;ƒïDžÍ¸+Éèò|·*Uªô€Žßá;ƒïð}å¢7ä´wkOžað($2èJ2ôÚq8ð}Þ¼y’Úµkç¾çcaÅwÆà{>ö5ò}ôÐq’žx¼4Ždð(T2èJ2ô† ßó›ßÄÄÄHÚ»w/|‡ï ¾¾'wêxÎ |gð($2âJ2îzÄïÖ´iÓ$µoßþï¡|gì!ðÞ¼œÒSRÍêñðÁw¢Èˆ+ɸkÇáÃ÷ÿú¯ÿŠˆˆpÿ<|g ¾{žïSÆÍÓ•3·à;ƒïqéÝ kÜ +¾ç\€öÙgá;|gð=Hð}ýšä´|þêÜ?¿~þ.|gðÈkns.½‡ßïß¿ÿè£ |‡ï ¾Ãwû¾ÕZñµk9‘ŸlÜøáÍ ?ëÑ5¾3øNŒÎq ºaÈ÷œGдlÙ¾Ãwßá{}´>C_T·v½VÍ[å%Áw߉<•±6ç3áÉw+666ø—°ÂwøÎà;|·mß´«jåXå¾3øNÞ‹¯Y5ÜÚq8ó=ð%¬ñññð¾3ø߃Ï>ì¾gËg«¯Y6o•i>ûô øÎà;‘w2ÐJ2܆9ß­¤¤$IsçÎ…ïùx/cðole ¾»‘QV’±öï=¹õÿâŋ߽{×?|‡ï,mÞܹÇí\ûƒÀËëÞ±—o͘ß=|g°eÒè©‹ç,¼<º÷´½´]>}““ãO¾b²’Œµ¾à»•’’"©wïÞðÝ›|g×>Ýž¾|iÆŠåø;[$$HœúBàåÔý%ÕŒ­ ß 0øÎì#Fo¿¾ÞváØå‚ú£†Œ•T-®ZàåÆu?’Óé¬ó!üÏ ß‰ò‘!V’ÖŽýÂ÷ììl9effÂwò­>MN¡ÅwøßÙþm‡ä´yÃvøÿ¼ð=xDÆW9h}ÄwkÆŒ’á;|‡ïð¾Ãwø߉B%ã«ý‡Î(kÇþâ»U§Nïßà ßúä;îìÞU€¿ðöåí½ÿyäÐO¶~rï`V¿æþ‰cÙÿ`ï,`ìF’0œc¦eóÝ233s833n˜™™9ffZæ=ffÑѧý£:«üÆÓyzÙÉéu©ÙÕívu{^ô¹\]½¦"»•ßïÛóçƒûóÀ÷¿9ô³m[KÀ\åƒï:¸ß Ë.¿Úµƒi‰øžS"¾¿vä½›½óÂO Åj/xƒ ¤œ20‹–ßóJF›½ò‹CÛO211&?œ%΄˜“€¹Êß_=ôV`Ü C8ýøjû…ßórÄ÷(!W¬±#¾WTT0~äÕW_ø~âûK+–ßsÃõŸùÔ'õ˜Î=ë,Ðó7{v©ö­uk¾÷µ¯Qú·lá.üåŽí—}ó›TéÒ™Ó'ﺋã…C‡^´à›o¦Cõöì}÷þbǶ@cæD'\(ùÒÅOïÛÇÑ3¡êW~çÛÉ6£:wüûÑÃÖ`ËÔ)tró•Wß=›4¶¹jfÿ¾jóóí[Ñcžª8¦ýþùs9f\PuÛzuUûÓ­›Cæ*ßñvõêša×]z v::oøøc4`ø{æÌúÖ—¿L³5kF|øî8Œ…•à¦ý.ùî¥ ¦/±ìÅÆ®÷Üy_úÚûîz€ª§}†ãî{sÜ´´Å û^{扚ž¡ö‚åòµK6Ú¼qå¶k¯ºÞ,árhøµÃo;½õ¦Û©R›³Ï:§AíRÞû0ÆL5m㊭wÞz·Óò‘Ç<µaD–,ŸÚo^µýsOÖâxÄ€10î×¾òujKê–ÎU8¾/žµœQ˜a?üäÒ9«’ õ†õj6<¼ãC Ƥg,üåo°=MJšóh°Šµ¹O>ò´µ¬ýLÝœÄñ=JU¿8 ¶Hñ)))a î¿ÿþˆïg¾/>¬FJ¦¯¬Z!O3|ŒæâóÏsM65Þ3g6§BL 9Ý4ü»½U»ÉÁÓœÆ i×ÖÚtlØ g O¶Ú,1\Êûnº1Ýrö€çióÃMÒUè7Mž¤ãò§ž4=ø2WøNcÍ•“«¿÷=óè[?5¸_µßD|‡Œo¹áÖ¹\S›:ÏÖ“f÷ÆÉkwmØ/}÷½8-­[.l5FLRø–Õ;«4xìЉ9-¹ûö{qŸ«Í”13]­AüÎõû¬+awòM ¹1-¾sÚ¤í\µ`-ú«¯¸†cøÕôà{à\â{ûrÿ7Õw¸ëçÊË®‚³9ÈÆ÷g”{¼Áöð†€&݉”¼cD|Å ÈÊ|å¸xñý÷¿ÿý\ÀDŒ;6âû™ƒïx ÍG¾uÚ”?ØGLÈèÎÐÄÅëøÝ¥Ù;wNòò;®½& ¦I$å¢_.˜¯: Íeíøqvßí3¦îr`Á<óO‹k7Lš Sn}|éœë/,_ZöäRâÀvø.;©ù†0£__óÖÓæGãJ[#¿ºz¥á»q9o {tÇ4WøÎ}íÓÁøî]y‹àÖ[·27¼ÃwÉC·Þ2¬}»Ý³gF|7‰øÞºi;ýy4.iv`ëÑ·Oü—3È(%YeBÔ)þõäµÚt•t3|Gľì!…›®•¦æSµ³-!Ã@|Ú¸Y„¬ìßrg¹”SÇΤ͉½¯šÓwÉ앤b$~¦_÷hë¢|ÃwIç¶Ýöl:¸~Ù¼ËÒŒ:6ô?sÂ\ixsÀZ†oøno½:÷sç*ßgOš/ @Ì[Äq-^|)Í—¯~ì•£C«ÎSFÏÈ={aÏ(÷xƒí¾Kú÷ĔҸ~­iøÞñ=J”¤«ü4Wðµ¨ñ™7osñ‘|ÄVïV»D|o]§¶þû~­bURO,Šôʨûê–µ6?Þ²IÊÁmÛ8|‡€“ÛR+’a P+RÇÇ(›PÖ勆 ¡ ^|޹ôœ¼ö‰»îT3âÔ“ø~ëUWøÖ²}ýzÒ[P~:öãòÍ:WøNVxµ_=vL²Ÿ‘Nöà ‰õãfØJÄ÷ˆï þ<q1ëøSE ×)Hgm ‘o¿åN¾ÃÉf\e]e<ܺ5å+ß”’ðNËê7Îécî×}€ôà©Ãwè9Ånü .|7Ÿ«|÷ÅŸ(öæ²K® 'ÙÂxcqøþÀ=e/HFéñ†ÛcøÞ§kÿä}‰É‘OÄ÷(Q,k"°Êïpå´Øñ©[·.Óqï½÷F|?CðV扛îô`+z¤WÓ&ÒÀÁ.~f\·®jó£Í¥±à×䊾Þ#[Ø·+(ß^¿V½u+/KGÔ@BàŠµ™Ð½›kÜ« Ü7|ש ¬—ž/Uâ;œß\eã;~t}H Q?}›7³~t¡…õG|7‰øŽZ0ÛÖìvUಪŽí[vÖ)\5 FšÉ£§;|ýè»É®ˆÞ–¿\§oÿ«0“E.sÁ"ÎlgÉÀÞCñåã{æØ¥ÈX·&Äϸ–BÕ§®J|§%8›Ç\eã;t:wê"×OY½Fé~ƒÛ»5¬®  |F~¼Áößå–#³°Á¾D|—D‰¦ò£Y9Žø~2„æâ÷¢¨ tæã{þåÿß ÑÜSz÷L×jMçs÷߯SV|ª1ñ0I¸d‰*džï ש‹±ÁÍ‘ï¹yÙ!ì´1¶ Um,ÐÜ q/ªšÔ³G߉oI6#ŠÆz¨ßÍË>W!ø®…üÛ©¤¡+ºEÉã'û©óðCÕž82â{þå´á{» ¬]aÓPª€S"%œçUp Ìã†ï ƒæØÅoØ] Á“²lîjQǰ~eÖé¡6CûL×Ò?U=ôD߉O/ñTlO•øÎZÏüæ*ß'Œ˜bÑ&ÍË[%‹¹·‰Ì±~ÜAs”NHÔøŒÒã ·‡S÷~eIxÔ¬G§>ߣDAT~À*Èñý²|ùò“QÔ{÷V¯%ß y :Oׄ­s’ŸÑ¼ãÚ¬T§‹‡uøÞ¥´$ßß\[‘ßɯ¢ãcK»ËÓ+eÝ*XyôUÕ¯Eó$¾@Ÿ7¾ãVÏc®²ñ‘rœ-æà·~"¾§%â;ùC\¸…•ùÓ»PA­Ñ˜nk: ߃qªøN†‚atü|ÏÁîr· Óù‰­`˜¢·“øÞ¢që¼ñŸz~s•ï[wá8[¶¯Ýãú±²oóáÜøöŒüxƒí±©ƒò+{wjÙ¸MÄ÷(Q@Sýp€Õ“ªˆï&­[·fj.¹ä’ýë_áWÅœñ/ïnX¯?SâR\•Q&¹ MYû¡mÝ爎8f)'ni‡ïð}¾ÃÙ8ò]! ‡…­º#„6ÕE+À=YXS«ª™ýû%ñÛßÃç*ß©å©d)m΂‘ß«”xCÊ¿Êò™öm‘ÎÇÌjQ‹¸`ñ¢ÃwØ1ßI3jиda­$þ][fZ™µÄ¨ =¤óÄ»Àtá{«&m …ïás•ï¸ÆuÊ´Œ86gÁŸîÇ"glÞ¬}øŒüxƒí±©³Vˆ¥QܽÈñ=J 4åç¦JñÝËÕW_Í•——W£ ßYñiYb\Õ‘Å Í™mJËúrtÉ"åNiY«¦ªÂñ½²BêIgŒIôñâÕ£àúõ£ª*<¾‡ÎUHð «oÝ*+|y 6‰ øˆïUJÄwãNW¸dáæÙµU¤–u¤YYKcÙp|ÏÎ=¯ÎÉÌèªÈxHú<»†‰ñ•-Þô4á{ø\e㻥y‹]?/îæf,é%°A%àùñÛcSGK׌í«ÔÃòyEŽïQ¢¥üÔJ[D|?vìØÉE9“'G|¯Æ¥«P¸ênq䨮]Ð#$pLº™ òVt‡ÅÁ ß-A M™ñŠqcH£ãú>â.gÇ(} `¥Âã{ø\à;ÆÛ[u¢í¢¤_0dpÄ÷*%⻡\çÌV~Æë¯¹1©'²\€®·…Âw‹~AˆqOç{F-‰ 1!ZTj… £?Mø>WÙøn°K>g›öf² Ãñ=üùñÛcS—Nûc¹Aîz±˜ñ=JpT¿5â{ÐLûŸíFïô¯Ÿß¾ééá£;œƒïŸÛl6‹²étú^oø.á»/¶Jðýã‡ïfÉÎ(Kˆ–¾r“É$ÊæóùŸ#¾KøŽï¾7>³g”%AËß¿´ñxív{±Xà»T…ïø.á»Y³Kj&8#"ñYø^cƒÁ "ºÝîjµÂw©‘ðߥêW¿ÿÿ÷ ßÍ™I͈Hv¾×¾¯×ë^¯ý~ß›MÂw|—ðÝ,‘ Îd'¾7³årÙét"âââß›JÂw|—ðÝ,yIÍg9à{CËÏÕEÄåå%¾KøŽïRýðÝ,a‰Ì¤f9à{Ó?nµZquu…ï¾ã»T'|7KRFDòò»^rˆï¹§§§(»¾¾Æw ßñ]úZøn–˜Œ²äe9àû·íññ1Ênooñ]Âw|—>¾›%#£,aYøþÍ{xx¨#x|—ðß%|7vOR–¾ÿ“ÝßßïÖS4iíß…ïø^§úä’ðÝ<3“˜,|ÿ‰ÿÁÿõ—¬ø.á;¾Køn–h¬ÿw|oä9øò6Éý]M¾KøîÁ ßÍ’‹?ÿ¼;¾Wï¢iµZÑ ß%|Çw ßÍ·™?ÿž|¯Þ_}Ñ©ßï¯V+|—ðߥ*|7K&#"¹¸-ïwÇ÷ꛬN'"ºÝîb±Àw ßñ]Âw³daâ0"ŠÛõ]U|Ï-—Ë^¯ív{>Ÿã»„ïø®CßÍ„ɈH"&ó‚ï[·õz= ¢l:â»„ïø®Ã ßÍ’‚Q–8L"æß·wãñ8Ênnnð]Âw|ס…ïf‰À(KV|ßöM&“(;??{{Ãw ßñ]‡¾›%ü’Q– Ì ¾ïÌf³ÙññqDœœœ¼¼¼à»„ïø®ýßÍ’| ¿ˆH&ó‚ï;¶××׳³³(»»»Ãw ßñ]û¾›%ö¢,ù—Ì ¾ïêF£Q” ‡ÃÍfƒï¾ãû>%|7Ûl6Ãá0ÊF£Ñû¾/꯱ÓÓÓççg|ß„ïø.áûoöî6BŠÃø3ïHðú ÁK‚×ð ^¡H}½«­OýyW/ªëe·½‰å2½¬ß/¯¿†<ŸÏÇãñòÚ‚|¿Ì]§qEcÞ=ß#ßÉwÆÈwÀ#jÇï«LäûÕìû.jš&=Îú–ùÎùN¾3F¾ƒsªÓ4‰Ú÷½(òýš¼÷}ß‹HÓ4ÖZò1ò|¯1ò°Ö6M#"}ß{ïË•‘ï*ç¼,‹¨yžcŒä{ýcä;ÈwF¾1ÆyžE-Ë’s.Š|¿ç\×u¢Îó$ßk#ßA¾3ò8ÏST×uιr/ä»Ê9oÛ&j†ù^Ûùò‘ï@aQÛ¶Ýó£;ùþrŸUt}Y×5¥Tg¾3VÛ þ)ß«mø3)¥u]E}ÛÏ-UòÇqˆjÛ¶†·4ä;#ßA¾3ò¼–iÛVÔqäûï?}°w· “qƧ4 MvÁ`°[ãôíÝ6ÑÉF«ÓV‹½÷®`Ð>·Ì¢í`ïöíŽÿóiÛË;?¿RJaÅqÜ÷½ÀÇõ}DZ°¤”ÿÑ÷¾¿ï¸^¯çÀSžç·ŸÀ§(±<ÏÏ1&JŒ|T×uažOã8š·À8ŽçS†]×™?E¾Ckíyž°Ê²|GÄîeY Ëó<­µÁ_ç;¶mSJ9Ž#¬¢(^õ'OeŠ¢–ã8J©mÛ žÏw¬ëª”r]WXY–qØ ðÌqj–eÂr]W)µ®«y-òû¾k­ƒ VEMÓÌól€yž›¦‰¢HXAh­÷}7ïF¾sØš$‰8\.—išÌo`š¦ûÓ]’$_8N%ßy­UU•8¤iÚ¶í²,ÆÀ²,mÛ¦i*UU}ù’|gì©®kß÷ÅAJ9 ƒøÁ†a81o|߯ëú`"ßñ‹½;݆Ã8¾¢`Øó‚`ƒY ö¢ì-këiueÉb³ÛMVÁ`ïAv¡x—ãïû>Ÿ ß0ŸŸ1æÞ<:QJ˲ÇÑ~ €q˲¤”’ËHÆ È÷ŸiÛ6)eäâû~QÃ0Ça>ÎqÃ0Eáû>¹A ¥Ü¶ÍòýæynÛ–1F.žç¥iª”Z×ռܺ®J©4M=Ï#ÆXÛ¶ó<[@¾¿·ã…a’ÆX]×}ßcwò]°üØ÷}]׌1ò†¡ÕþiùŽw5J©,ËîóO¿qΫªÒZãgŽŸ CZ몪8çäáLš,Ë”Rx!óùŽéS!DE®ë’JiÇMÓc–e±ÿݲ,Ƙ¦iâ8¦”’×u£(Bàè òý{õ8¿~)e’$÷=×›ã8œó<Ï»®ÓZOȿGö}Ÿ¦IkÝu]žçœsÇqÈŸÎDI’DJyF ¦8ïð÷›_ìÚ¬@!Æñk¹äk9¦9¥å¾åkaÎaÞrÈ×–/O³’è=ß®¼íÚû~®gûïì+¥xï•RŒ±ç !„s.¥4ÆXkC1Æœs­µ÷>Ƙs®µÎ9÷Þÿvcø Þ{Ï9k­9ç£÷^kÍ9ÇCÖZcŒ”’sNyÞ0Æ”RÞûRʆ1€|‡½wk-¥äœÓZ !(¥ÀG(¥B­µs.¥ÔZÛ{ÿò>ôÛnR ¼÷‡ÅS€D !HA jЃ øÛ»3)æ½wï=çì½×ZsÎ1Fï½µVk-¥äœSJ1ÆÂ÷}ÿ€?ãû¾BŒ1¥”s.¥ÔZ[k½÷1Æœs­µ÷>çÜ{ß{ÿÑw@ß@ß}ôôÐw@ß@ß}ôôÐw@ß@ß}ôôÐw@ßà÷ønÅé' :IEND®B`‚ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/images/ovsdb-relay-2.png000066400000000000000000002440631504532661100263560ustar00rootroot00000000000000‰PNG  IHDRî:|µ¥ÝGúIDATxÚì×1Í«`І„…‰õ®`&APÀ‚ f ãêÀ¾.}2^›ÿçõ€Ÿ¢²¨,¨,¨,* * * €Ê€Ê€Ê ² ² ²¨,¨,¨,* * * €ÊòãJ)÷}gæu]Çqìû¾®ë²,Ó4ãØ÷}×uѶmÓ4u]WUõ€¯TUU]×MÓ´m]×õ}?Žã4M˲¬ëºïûq×ueæ}ߥ”Ï—Ceyž'3Ïóܶmžça"âXD Ã0Ïó¶mçyfæó<Ÿÿ•åýþÇÎ@¬ÎpA@Q˜@"BŒ€p d4!$A˜€„PaƒL(LJŒì»ð²ë^\®ë{ï{ŸÀðø;'<óù¼ßï×ëõ\.§üL"‘PUµZ­ !z½Þp8œN§‹Åb³Ù¸®ëyžïûÏçóõzA†áûýŽ>%àý~‡aÁëõz>Ÿ¾ï{žçºîf³Y,Óét8öz=!DµZUU5‘H(?“Ëåêõz¿ßŸÏçÇã1 Cî–”Åt:,Ë2 £R©(?H¥Rš¦éº>lÛv]÷ñxDþaàñx¸®kÛöh4Òu]Ó´T*¥ü R©†aYÖétŠ@Êâ÷)e£ÑÈf³Ê÷J¥’®ëßN·Ûíý~ü‚ûý¾Ýn¥”º®—J%å{Ùl¶Ñh|;=HYüºËå2›Í„étZ‰QUµÙlN&Çq‚ ˆ~€ Ç™L&ÍfSUU%&N !f³Ùår‰~ ¤,v»Ý`0(‹JL¡Pèv»¶m_¯×èp½^mÛîv»…BA‰)‹ƒÁ`·ÛE߀”å÷¦årÙétâl&“iµZ–e‘¯ÿ/µ–eµZ­L&Ÿj;Îr¹üÿ‹"e±Z­Úív2™T>”ËeÓ4lj|2Žã˜¦Y.—•Éd²Ýn¯V«èË#e±ßï Èo°µZMJy>Ÿ£OÀù|–RÖjµøNkÆ~¿@Ê~1·Ûm<ÇßÁjš&¥ô}?ðò}_J©iZü=íx<¾ÝnHÙ¿Ýz½B(òù¼išžçE¾ÏóLÓÌçóÊ!Äz½þ½;Àðˆ0>€]§  è(™Ó€è!è …·D –]vwÛý¿#$øÌ›7RöÏY–Ås_zDZµVüSÖÚ8ŽïÏ‘c–e²Ï7 C–eŽã\¿oUUó< €0ÏsUU×±–ã8Y– à eŸ©mÛ(ŠÔIk]×µxIu]k­Õ)Š¢¶m¤ìsXkÃ0T§4Mû¾ç³èû>MSu ÃðIY¶:ù¾¯®ëæy>M“ÀÍ4Myž»®«¾ï³êwRMÓA žç•e¹®«À;Öu-ËÒóö}7Æ\A«µîºN¾)‹q“$¹Æ‰‹¢Ø¶Mà“¶m+Šâ9N’dG)ûå“oìÝ/ˆ´@‡ñ‰b²Z´w°ƒ˜lF£ljF›E°Xì½ ö"6‹É^~ï2Ëo8îöÏ >Ÿ-3~§,KõPUÕqO8Ž£ª*õP–%ÿ-’²/Ó¶­ëºJ˲l]W€Y×5Ë2¥¹®Û¶­€”}ò·X3PEÑû®° >¢(2ÇÔ)ûËÅyž+Í÷ý¾ïÞ¬ï{ß÷•–çù†Áó<¥EÁ¶€O.BE¡4Ïó†a²ßÛ¶-MS¥…a8M“ÀÇMÓ†¡ÒÒ4ݶM@Ê~©ë:ÇqnŠeYMÓü©¦i,˺EŠã8]× HÙÿíûnc“$a£Àyö“$1dzû¾ HÙ›qïoíØ¶Íì5€s>jÛöýµžqåâHY3SÇñ²,rJ°,KÇfܘ”½¨yžƒ PZ]×rzP×µÒ‚ ˜ç™”½Üéü?öîDn4 àøó~t<”¬'^ÄêÍ’x×ÐUÕuUŠP3^Ä„…z¬QUaÉ…¬98Ž;nv{;™ßÏ{øó}ï½ØÝÝÝ=>>®Wâñññîî.v74#)e˲ŒÝýýýóóózUžŸŸïïïcW–¥”=¸§§§,ËbgÃpŒß¦Y–===IÙc:ŸÏ/gc?|øðóçÏõÊli³ÎËáÙóù,e;ýñãÇ_¿~­‡°Ζ9·¶Ñ6nj8öááa8œ‡‡‡ãŒÎJÙyžó<]Û¶+ÀAµm»<Ïçy–²×jÇ4M#"I’aV€C†!I’ˆHÓtG){}ú¾?N/»¼¦iZnÀ4M/w[N§Sß÷Röšt]»¢(–eYnƲ,EQÄ®ë:){š¦‰]UU+ÀMªª*vMÓHÙ÷îëׯ±«ëz¸au]Çn %)û~}ùòåhÇ”.°ÅQì¶\’²ïÑçÏŸc÷íÛ·uÀ–H±Û¢Iʾ/Ÿ>}ŠÝ÷ïß×?` ¥Ømé$eß]Ƕm»þmÛ©fã0ÿŠüø±þ ¶h:ÌOã8Äž§~ mÛclŠÜÝ1ûïæfÿ· =R¶išKöØiÜ4”ý}º®»ü~,€{³]×IÙß¡ïûØÕu½þ'Ôu»¾ï¥ìÛÇñt:EDUU먪*"N§Ó8ŽRö­Ìóœ¦iDE±^ €¢(""MÓyž¥ì›Èó<"²,[–e½˲dYyžKÙ×W–eD$I2MÓúJ˜¦)I’ˆ(ËRʾÉr­aÖWÀ0 ¯|&FÊžÏçØµm»¾þ`ça$…¡0Ž? U…Æà°Å`ðT-ÞÔ`1…¨Y˜ ñ©KÆà ¡·™MæFÎÞäö’ãûyUÓüóòÀÇÇÝ].¤ì»n·cŒˆ¤”æ¯)%1Æ>C )û–¯ýã,ËÌY-Ë2ŽcÛ¶eY&IÂ9÷<1fÛ¶eY/³,˶mƘçyœó$IʲlÛvÇeYŒ1eÙ×µ]¤ì»§ž‚ ضíl[×J©<Ï}ß§¾ïçy®”:ó}A€mÛ‚ øóPHÙ®ëèNkmÎaš¦ªª8çôÄqœ(Š„u]÷}¯µžçy]×}ßã0ð²ã8ö}_×užg­uß÷u] !¢(r‡žpΫªš¦ÉœÖšîº®CÊ~Ïõzýýv' ”Šãø9_Ó4mšæó üÔ×Ó4Mš¦ÏYDZRÊœÌc²ø½$AʆaHDBˆÿ~VJéºî£`‹¢†áߎ[0¼†¡(ŠGÓº®+¥<Õ>-€‚ˆÂ0Dʾê{wb+Fqü³˜§Ú›E»=YÄhÇj± öb°×Ú“ÁfOV‹Éjyà…–}ïÕÝÙÿ¯w83çE!"AÜ÷m,už§ÖÚu]yDQÔ¶íu]æÛ\×Õ¶mEòp]Wk}ž§ù¸ï;)Š‚(û}ßËcYc©¦i”RòH’dš&øÆ¦iJ’DJ©¦i ¿À²,òèûž(û/Çqxž'"u]ãønuŠãxžgóCæyŽãøÝ 5Ž£±u]‹ˆçyÇqeÿ*˲WÆ36*ËR¾ïÃ`~ À0 ¾ïË£,K€í^/¹Y–e¿ÖuÝ«úhÛ6c—u]ߟ±UUÀWUÕû{v]W€½¶m{U!v]G”ýlßw¥”•ë;ŽãˆH†6]÷ÆaŠˆã8¿a°À6Rjßw¢ì§Åiš»h­å‘ç¹};ÀlOžçòÐZ앦éç3ã?ìÝ­@ÅñvРZJ$ZBK¨uԂЂ‘€à‚vóÞëÂÛÁeúÿvqÌ|çeçy–†áyžÎ#MÓè1 ƒxj=š¦qxê<Ï0 %ÍóL”ý纮$I$ãèÖóÎ ¤Yc w³u]')Ïs÷Súy¡sš¦÷}ûÔWEÑkÿ¬µQÑi ðÕ}ßišþ|HU?l{ŠãXÒ4MÞìÇêAÏÐ¥‡—{³LÓ$)Žã¿±îuQ¶ï{IeY:/ìûÁÿ»;z‚ Ø÷Ýy€²,%õ}ÿ®(ûù|þ°wÀ‘­YÀÏÚ(Í”¹.,SZÛ¶mïŽmGcÅv:“ӈm¾.†Á÷þ•[ÓÏî¼ôýæÿ«ï½ñLçÞ:uΩOîÖBDD„ˆüîw¿S†»K·gÿ7=4ÛÝ:ÞÐ<쮨¨î³¹º-¹%méE¤|ßõlÏ¥ôƳÉu‘q5ǯTºàÜkßq¦ìß'Jþv¤øø~cß_Âoˆ«>žTw&­!6Ës1Ï{ÍH´¶¦•wd;» ªz‹ëúËš†œÍ£s}ó7^Z¾§ˆˆñÞD Bi‡ˆˆ(x‚/𻍕ýéO*"¿úÕ¯”¶lÙ""ï{ßûVWW•.VVWoÍÍtMúPƒ:ºò ýñ)õÑ]ûO–þýÐßmø8]úÏËî© 1‚£«²sÒ‹¼xkvyeIéˆñîDiBi ˆ ¹{PZÙ`û>88¨ÌÏápÈšªª*eN÷–ïŽ/ úFªKÛ33›Î_«:U¾õ™ËУÖ?EUl»è>˜P{&µñ\†çRvóµ<_|A ¹¨5ÝÚžUÚ‘WÞeqôXÝ}¥ÕýöºAwÃpµg´Þ7îi™ðµOµb´LøñCüdãp ~Cõ€ÝÝWæì±Vt•væÛÚ³o´fRòü 9Þ뙞ËiçãjN]pí?S¾“BÏü 1_„™"L+a¢©e¬~jqteuYi‡ñæd ’…"""Ò ºÇ.¶Õ¿•ýò—¿,";vìÐiiñîÝ»•y,Üœé™TõZs½W.ºö=í´IÙ¿Î9÷^¯9õ(jSg­~¨Ò?îí˜nßð24Jgk{vž/!µñüõš“ç{ñ±ÿþ)¿"Ìaé#ÖRöL·à!(¢õÇøeü"AèºÌ˜ˆˆmˆ ÅÓ¿•µÙl"ò–·¼eqqQ™_TT”ˆ¼ç=ï ïI›;X¶ç©*iËH¬;}ªôO®c»ë¢ IÝE5Žæ±FÔš¦Þ±¦ÚA&ˆ0×_{:Ú¾ãÉ_5Ebíi[kšgØ=2×wûÞMEÄøeü®¤ AÊPz!""B[‡æNDÐèiÞÊ~ò“Ÿ‘£GêñÚÞúÖ·ŠHnnnëÒ5å·µ¥_pí}ªðŸWªŽ`É_IG.êÅö©6ÔŽÚ¶É–š'榰œòJå<„'?™Kî¥íY˜óÁ¢M"DŒ_Æ/Ò„ˆ e q(½¡¹4z:·²‹ED6oÞŒKu•ùáîûàdz˜ŸIJCœ#úØòîpñÎ:v'ÕG’½6Lw¥!…«×†í|Éõ1çœ{ŽZ·/¹> K± Q1~¿!Ú\ƒÄ¡ôBDD„æ-žˆ ÝÓ¶•ýÄ'>!"§NRæ733óêW¿:N{Â9¥þÑš|ï5”òØJgºäúâ«ú+ž{iÈQÙWžã»à:ð„h°CÇê,ÜœUDŒ_Æï‹8ÿ ‰éCé-žˆ ÝÓ³•µZ­Æ”ìÒÒ’2¿}ûö‰È7¾ñ µAújÃ8äó±EN%Åé)8z40á{1!G`Â[ÞUˆÃ]ñHŸ´‚1+ÕóDÄøeü"eˆÒ‡"""Ò Z÷99vì˜Ò¦M›6är…™ÿMÙ;ó¢Ê·‹³c¶¿àäO\¡Û2Ö£(äÀƒÅã«9yÜö—àc,ÿ7^ÄÌÿ&ã—ñû|.oCúPDDDÚA£'"hútkeÝn·qpñÍ›7•ùÅÅʼnȇ?üaõê˜ðà–Å`)†k6²½×p‘ãK[rc.É<ÿ˜PðR:&›ã—ñû qˆ’ˆ"""Ò =ã(c´~Zµ²ßýîwÃàòÕoú½~ýºZsÿÈÕ]}™n\L®Å–°­9°‰1¥!Gòï%ƾÝÝSÄ»j‰ñËø}fH!ØJDDDÆW©£õÓ§•mkk“5“““Êü:;;Eäõ¯ýÝ»wÕzêšòe6]ÎàSKK*ö€…O9È=x)x5Á×”í¹Ä´Äøeü>$¤A*QDDDzA»'kÐjÒÊþå/‘ßÿþ÷J ‡‘_üâjÝ4 ¹Î:v««¤ú(woi8W„®Þ’ĺ¨à+;ïÜ[?P¡H7Œ_Æo }ˆR‰"""Òš>A¨C+»°°ðªW½JDü~¿ÒBDD„ˆ©u06ß¼U2ƾ³ ì÷˜¨"äE—ùþ¤èŠíÆL¨=52×§HŒ_Æo }ˆR‰"""Òš>Aˆ6Ðô­¬qÅ®†WZ1V¯®®ªZZ¹WÖ‘m”PgÊ·”vä™·"äÀE Á[@pçÊòÊ’"0~¿!€ôa¬1FBQDDDÚAë'"hMßʾóï‘ÂÂBºœ]òëd[ÇbîOdz.·Mµš½ähŸnËô\1Þi¬}gûD“"M0~¿!¸`V×sŒ‰ˆˆÐú‰Ú@s·²‹%øeèáç?ÿ¹ˆÄÆÆªyø¿Y÷φ¹\y¸zÀ®S9ÈQÝo¿ä>d¼ß\ïÕyÓqLŒ_Æo ‰ˆŠ"""Ò‘1‰fÐÄ­ì·¾õ-9qâ„ÒÅÛßþvñz½**{‹"éxÉ_o´fèZrXZÒŽZÿ„}ÔúÇúrE&Æøeü†’ˆˆ ¡("""¡4ƒfme‡‡‡eÍôô´ÒÂÌÌŒ±QV…Bi{¦QãzCíφáh­O¬‹4ÞxUo±"cü2~CÀØ.‹´¢ˆˆˆ´ƒPÖ %4e+{äÈùÁ~ ta·ÛEäÃþ°zÑ ýñFUTÚ™ÿà”ƒ%¹°wArY½Ã³2Ãn˜Ìì½ö1Ì´•™™¹;ÔbffÆ.q£ ÄÐb–™™)ç†2¦¢ÌîÖ·”ÿ÷9qmIE‚—/ò¢Œu_{°!äȾ ýë­D’·•+®íÕ˜` Ö@IVÂ\ªìYg%©¾¾>…þýûKêÚµk8:&¯àa¨¦tMÃîúÎ6 ’y['Æixë“å ûþ%ô¯·IÞVPYBPÙB` ”d%ÌŸÊ644HúéO Ä 7Ü ©Gá(X¾s–Ç ‹oiÝ¿¼s΂dÆÆQqÞóÜÖ ûþ%ô¯·IÞVò¨²{žý0‘‚ʤŒeP’Å0g*{ÅWHºë®»Bøýï/iÆŒ¡£´=¹&Î@ {Jy$“× ö2¨©¿æ‰—÷Hìû—пÞJ$y[Ae Ae‹ €eP’Å0g*{ÒI'IÚ²eK(—]v™¤r¹:Äëï¼R[ºÖÐìÍã˜ɸÕ}¼z-¹Í #@Òdß¿„þõV"ÉÛ *K*[T,ƒ’,†yRÙ™3gJºüòËC±øÉO~"iÿþý¡C4ìšãÑgÔÊîL$fÄŠn^^’&ûþ%ô¯·IÞVPYBPÙ`%”d=ÌÊþë_ÿ’TWWŠE|©ùå—_íçÃ>¨[t£çž¦½‹IŒƒ—D÷E7}ôñGÒ%ûþ%ô¯·IÞVPYBPÙ`%”d=̇ʾÿþû?üá%íÛ·/‹ïÿû’Þ{ï½Ð~Êû—yèÒüó©Îই8›'y²ï_Bÿz+‘äm•%•-0VBIÖCKbTvúôé•ÃW Æ·¾õ-Iüq‡¢\Ð6•áT§~Û4/ŒÙGH—ìû—пÞJ$y[Ae Ae‹ @ØÌðGªS>Ô×F€ȼ ý‹Ê‚Ê€õP’U1i•½ñÆ%ù0Üðy ²‹wÌbø#ÕYºs.*› Ù÷/¡QYBPY°J²*&­²gu–¤–––ðy ²Ó6 gø#Õ™¹q4*› Ù÷/¡QYBPY°J²*¦«²»ví’tê©§†/•õ‘ú ¤:#WtCeS"ûþ%ô/*K* –DIÆDUvÀ€’þñ„/•uZö-eþ#1^ •… ²ï_Bÿ¢²„ ²`I”daLTeÿô§?I1bDøbPÙÑ«z2’/T61²ï_Bÿ¢²„ ²`I”daLTeã1<_*Ûcñ-þÃîS ñ2ˆK•M‰ìû—п¨,!¨,Xã‘<)ªl¹\–ôë_ÿ:|1¨ìÜ-üÿá­µÛžiëÌS ñð2ˆK•MŒìû—п¨,!¨,X%Y“SÙºº:I]»~ÙŽŽÊzµ²»2¬µfóS:çH\úa-5^^ þ%*›Ù÷/¡QYBPY°*J²6&§²¿ûÝï$7.|)¨leÜôÐúÇËm $.ú ¦‡*s0*›Ù÷/¡QYBPY°*J²6&§²§vÚ×ü ,*[™†û7ÜW>ÔÚy¦@R>ÔÒ¿áÞÊŒÊ&LöýKè_T–T€ËZÓRÙ¶¶6I?þñÃו­LÃþÖúmS;ÃH\h—»2£² “}ÿú•%• £$ËcB*¿[ùïÿ{øÚ ²ÎÔõÃâå£Wö(j)ðÈ‹9.q¬µ‹îKPٴɾ ý‹Ê‚Ê€…1žÞšÊ^qÅ’zöìÚ*ë,Ý9·÷Ò;|U·…7ÌÛ:‘©±xqY]\—Ø…v¹} *›<Ù÷/¡QYBPY°0J²<&¤²—\r‰¤–––ÐNPÙø="cW÷Ž7ðqZ"ˆKOìp\âø-A¨lȾ ý‹Ê‚Ê€…Q’å1•}ÿý÷u„·Þz+´T6fÞÖIÝßo6¤ù‘E;f1Jæ7.Ÿ‹«é²º¸ñrT6'dß¿„þEe AeÀ¨#X!“PÙµk×J:÷ÜsÃQ€Ê:ŸX;sÓèžKn‹7Øø`iÛ4ÆÊ|Å%sáb]JÔeõå¨lÞȾ ý‹Ê‚Ê€µQ’2 •>|¸¤ÿüç?áè@e+çïÏÙ<¾Ï²;ã]|öìMc?óƒ¸@.S<¨Ãqù\D—2^‹Êæìû—п¨,!¨,X%Y!“PÙë®»NR]]]ÈT6¦íé-~W[¿å÷Ä;:#Vt+m›¾å©éÌÄåpQ\šJ™\2Îå‹7@e ý›Uè_T–T¬’¬I¨l—.]$•J¥¨l%Kvε²Ç# ®øÿ·nž¸f@ãž…Œ¡Ç7. árĺ¸@.“‹U¹*[$è_ú•Eeó•jû]}Ó=c§/éØÝç7lòÝo»¯•€Ì±6J²B&¡²gžy¦¤Ã‡‡¬Ae«ßÿæOmU¿ÈÓ¿á¾)ë†,Û5o3¯ó»×p6-ßµ`Êú¡þǯ~Ç¥©¼ƒ•Eeé_ú•%Ç2[¾>dÜgýî+þâWgKºö–û:ö˜=Ž“têig ²™ÖFIVÈ㯲Ï?ÿ¼¤O<1|“ ²•,Û5̪^Õ_]ÅjJ× kyÌÓXë¾eL«ßDVhœ»e‚ß…XSº¶òÏî¸.Gåf¨,*KÿÒ¿¨,9öY¼r»Ž0½´ •Í`y”d‘<Î*ÛÚÚ*éòË/ÇT6fÝáU Ú¦xë±ø–øÈ•·/Ž^Ù£¾mj<‘t8žX³xǬñå¾=–ÜZý/ì/5õ “ Ú¦ºí}LT•¥é_T– ²¨,X%Y$³ÊŽú{g[G®…a?fÆeff(/3•™™™“”’,‡Ë C9Ì̹7 e†ô1ÓòþzGkÍÎÜ—Návš¾ÿב4ã±=Ç–,ùÓ1lÚtá/&Ê­d.B:kKWC=° ü…‰îÕ…{3Ψ6î Û\»6¤`‰±'ý3&#¤“Ü[~°À˜™(K”åøåø%Ê^ÌÖxð/…®ýmÇÿu¾*tïýýžöÏ~%ð¡¿¶ûçùòëŠáM”Ý}â?Õm§:®MÛ{ê#¢ìEñc€¤Ã(»hÑ"øáçççTGeµµœj*Ø›Žé¯¾RB[pÁ"„€p½¦zõ'Ü’Ÿ†®@‡ [Ð9è"S§…ùn­ßX¼/k¿N¢,Q–ã—ã—(ë¬í>ùÁ<ŸÀko¸Y}¡»î}ÐxR—OÝrû]O¿ðšµì³/½OoôŽç…~oãyüÔù®Ý¿í;hÔ¯/»U}ïû?@ñ¹®Óº·³Åy¼0rúÊZ¢¬îëŠeتw×e)Šòª€J)à¤c(&NœèlGeiDYŠ(K#Êe5ûa‘°õÂXù¤O`ªÛ÷GIAprü´&ž´²žÍ.ÊÚ÷Ù (‹…ÐRÐt- g)e)Šòª€J)à¤c(ëëë |||œí¢,(KeiDY¢¬Þü‰Ð¨1(ˆM°r˜°1ýÕ>ƒVe‘0öÍ^h”µï³P¶ªµ] ¾üÆ@c¬ˆÆ¯‰²EyU@H¥pÒ1”2e < q¶#ˆ²4¢,E”¥e‰²»O~pËíwÉéMÛ²ª$qOû‡8ýHz;f{¾1?nRUU¶œ¼À(kÓçŽQWÑJN߀û(k<òñ–”æ#—ëg‰²EyU@H¥pÒ1”4h<ˆ‹‹#Êr*L#Êei¿DYÇ 7ßh4Å¥©]z<D´Æuä´&_Ÿ~á5¤\x”µï³G”5=…‚Ø÷ke±­W÷–_3*KQ”·„TJ'CÙçŸddd8ÞDYQ–"ÊÒˆ²DYŽn’㈚³Ä_®{5Ù¸)ó$Ú˜dÓ§QgyDÙ¹Kì`*”šç4¦oɨô¼ª=ö}Ö×öx< K£u)Ô‰ôNãcÊùÈã=ŽkcuJyã1´Qôâkýcwe)Šòª€J)à¤c(Û¥K}†²ã"ÊÒˆ²Q–F”%ÊJ¸w¥­Mx+4 ”ˆ¸è%ï3N±Bñ’úÚ~íÖ3g—·b³îº¸TYeím#ÊR%·º'CÙ»ï¾455e9¦e‰²4Ž_¢,F”¥(ÊŽ€J)à¤c({ýõ×Ãe9¦e‰²4Ž_¢,F”¥(ÊŽ€J)à¤c({Ùe—Áƒööv¢,§Â4¢,Q–ÆñK”¥Ñˆ²EÙR)œt eüãÃ?ýéODYN…iDY¢,ã—(K£e)в# ¤R 8éÊ~÷»ß…ÿüç?‰²œ Óˆ²DYÇ/Q–F#ÊReG@H¥pÒ1”ýÆ7¾>üðC¢,§Â4¢,Q–ÆñK”¥Ñˆ²EÙR)œt e¿úկƒO>ù„(Ë©0(K”¥qüei4¢,EQv„TJ'ωΜB;¢l'µ…;&Ì?ké,yNŽÂ«Ï›>¿iDYŠã—F”%ÊÒˆ²å¼ÈVDY¢¬WìÍð@tÂOþSy¹x^o¿ëvÎh‰²DYŽ_Ž_¢,F”¥(Š(딈²œ e)Ž_Q–(K#ÊRE”ews*L#Êe9~9~‰²4Q–¢(¢,QÖ}ЕãÊi<ÞpŽõ´´75Vï­:m¶ÖS-v¦ÂÍ'š êó[N6Ÿ…3hN~]^ýÑºÓæ¬Ù_m§ÂºÃµU{+Ï®gj¹Ñ–ÓfCž²¶2tQö’Ç/Ç/Qö?ÿùÛíÞ¸qãŒ3žxâ ¢,(KQQölD”Ås¶Ïìko¸V}¡;ï½sãÖ :Ãã=»ùö›ŸzáIkÙ§_zŸ^ëÿ𼦔$?ñܺLmû écb†v{¢Û÷¾ÿ=XÏgz® ZSᬪLäÔ>Òõ‘äâ6Ûµ&a5jÐeÑ@4óoS¶¨‘âŒ8ðJß—cR¢–½ã‡65ó{x‹l7Ü|ƒý>åºs^îóÒ¯.ûÊJ“W¯4Ù’»EàmñúQ“FŠÃe­¥DÙKC¿¿DÙ£G¦§§ûûû8ðŽ;îP_Q–F”¥(Š({Æ"ʺÔtéÕEyÒè)£%Ï€ý%%»:ËXóTIŸë;¯©¥)Ê“®¼æÊŠÝåR‘ŠqÓÇ*‹0µN…!™¡šqÚv„(O2M^§ÎŸªgï€=Wš(¾ekY¶>ÛxZÛ¶mÛ¶mÛ¶m[ecû~U]¯k*ÉÞ›åß}çT/2™d’¹™º§ët÷ñmÕ@>T…e[—Bû¬Ń>K6-¶Ã®ý»ØUŠÜÁá7…ÿotvц…îhZ @±K&ÍŸèlrÖò™ðÈq³ÇŽSaCÝfu7Ù¼÷ÜÞcX òÈ™ûÙB1­'Ú Û„ [ïÇ Zã¦C]öñn«v­¤ï‹¢e¦k9&4µëÑnÂÜ )çäÀÅýîÌX6!p|¬‘ÉPa›„&m›ð²ü,äÊæ hýjýæ~WÑuÓ¦Mˆ®Õ«W‹® @?üðáÄsçÎ%´øÅ‹Ê••É•A®ì‡C®,tÍF'Œ0l'— êfÌϤ;„&†Ý ³4€íд‹Æm‡}¸³Ú}¸¡ñB²Î¼ÏÖ£[ÞE…›wlÞ¸¾¸ê·uûÖY7Èn˜Úgo—5ºl1™øËàÊá»[$a©Š¥"T¸X™b–ˆ˜~NªÕ«jÚS> AŒö¾–zçT˜{¼t@eŸäÊjýjý~Í®ì³gÏÒˆ®5kÖDtݲeËÇUöI&WöSB¹²reGM:Üj7®e§ŒüµíÞÖwÞéiuÖ2aÎxkñ CˆlÏäJ­ðÿ͇7Ù%ƒÆ Š gBGœ sm¤ ´Ò¤ËäΡ™âQ‚û÷ßÔ/G â†VBfõ®UÖq)ò0õš×ów©ðÞs{¼Oš9.Û!1™‘!&/˜d§o\RáQÓG©‚±\Y­_­ß¯Í•½ÿ~ö¢kÁ‚];tè€èzúôiDWU0–É•A®ìg„\Ù6][‡4Q?!8Ã'¶ÛaÏ!=B­bêÅE›whFÙUªYbGH§"dåE†ë=¼wœ £Ä̪ÈPyÅë¦:\>ÂÐj¼‘9j±@y‘›5ÆÎòœPÕЈW´SDlÚ›Æg)Íœ¸hÆ #C˜ÚðFB*LĦ\Y¹²Z¿Z¿™ueMt={6¢ëwß}—(ºþîw¿Ct>|8¢ë£G´L®¬ _reåÊ–«Z.bg6{å,{0’ʬå/ÿü‹UO±C ϫ۴Nw‡Ð/‘B\ßþ ûèÐgxk9zýHd¸ñ³ÇÅ©°óÚ¸þÓµJªï¢Âl%B-ÓÄZ8ؾg»<9EÈ .ÑŒác¤™›<9œº (WV®¬Ö¯ÖïveMt2d¢ë¯ýëDѵpሮóæÍCt}ùò¥ö••É•Í$A++WÖ´…Dñ„j(‘è;×y¨àâÑ}T[‰\ˆ ¦ðI¸‘ÿ'Z/¸ÃžÈU0Â8&ç-ÒÍ‹Ó/[œÿ³‹&l84†;ùQo(+jésN!ÅØ!cQ.5Ñ,<2™ §˜o!mï]CK)Wö—­_­ßÌ»²OŸ>=qâ¢kÛ¶m]óåË—(ºÖªU ÑuëÖ­‰¢«\Y™\ÙLB¹²reïÂ_ã›+Ú)Ó@°ã7[ â L7¡Ùæ·vÏšHYd»Šp>*£FŠ‹ºYyÒx®!…‘-4铘½—‡1–鯳y6`- å0B ¹œÒ©v˜L…S̉Ÿ­X£‡‘¤A†ÀHÿ“++WVëWë÷³º²ˆ®7nDt­V­Z¢èZ¨P!D׎;"ºž9s&…è*WV&W6£A®¬\Y§ƒè!a;ô—8Ãxˆ`™Ê¥-ÏDÏ1Ãæ¯›ææ¹ù¦+¶/g£EW9Â>TCµáâTxèÄ¡aOòå¼´išB¯^¹-í(B?¹œD>ç¾ÉT8Ýœ`ÖÈÛy‘U³n»ùžres´~µ~3ïÊΚ5 ÑõÛo¿M]ÿûß#ºŽ1ÑõñãÇY_reereA+«é¹½=tçÌ£“Æ–àg”T1®¶|Û2O™C…°§‚¢%2Ñ8o#·ÍÉßsˆû×oQ?Ôgj6¬i‡½†öôª¤Ñlö¥d¯Hã‘ë÷¯£ƒ‡;fó^ìi×öÑ×OÜ:a Sã|È) 'ûwìÓÑ» 蚆 'ÏI,‚±E§L¬{ L¸¿ùT˜O‚ƒÏ#+2¹~µ~µ~E×"EŠ ºÎŸ?ÑõÕ«WY™…\Y™\YAäÊjºçã9pkÇs¦ëç‡qÔꄥŵW{ŒŒ‚Â%ˆœeGJ;…”A.Ü÷Å¿÷[A­QýüÕÈú$ª:ΆÉrÞ‹ûý ,¤¶ª?õ`xÙd*œzN̯ð¡éÆ ä/E†Þg¢Â|||Y€Éõ«õ«õkS»vmD×mÛ¶ÅE×ÌC®¬L®¬ re5ÝëÏÍ…ñl¾´âcheN¬tgˆŽ½;$*'T(!nè6¦áDмcsv§ áL]q”,_é&¤Â&­À,»êîlÕ:ð´i^jÏÙÝV`Æa—G6~„ Gº1\ç¾y—H¸£'Ñ¥Ÿ3¶Êt'ÁA%æ!Þi{Ÿ|¼ñIðaðydeB&ׯ֯ÖïÏàw¨\Y™\YAäÊjºßÙ ã™~`ÐG2'¤ öŠ=c45TàšF?Ìà Äì ÝŸ¢¦è'pMãZûdà7uñÔu $š•;W²Ûe`Œ§· ÖCO{ëÅX­!©/±U^é6hÜ BÝ8JË'·#×Ï]=‡9™8oi~´|Vã“àÃàóȾbhýfoZ¿ree2¹²‚ ȕ͵ÓýúÍ+K·ÛÿSŒ¢LÆÇ`‰v?²wL’dQþUó“Ö¶5¶m¶j—­.¶mw=¹'"'k´²êûâ,§ðÞ½ïDÞ3ÈÔñ0`›²þþEø—(‹Qˆ²V*·½«jgí›W}¯ßB: ::ƶðï: ÿe"ÊQÖJå¾÷xqŸíýµoV&n2"  cÛøwÝ…‰²e-Q–r§ÇB;kß”ìÝ6fÁ|–½Çfž ,þ]á_¢¬U…ˆ²@”¥Ü¢­³bg훇›>óô·1æ§Ôz,þ]á_¢¬µ…ˆ²@”%ÊŠÂðéµoîµ½gï®g.Ì7©éj½€Žÿ®ÿæe”݆BÈ€õ‡(K¹ÿò1•RcGEþLHíVÓy¬Õ1ý‹ñ/Q6²@”%ÊŠÆL‘9Ý žˆEs[j±mv\­7¬ à_ü›§Q€(K”5qõÔ™³Ñ¾†jS…Ì‹¹*5W-6{­¦à_üK”€<…(K”3÷Æ‹ÃgÌ!é¼k—§¯5·¦@îÓª¶šýU£ÕnÃêþÅ¿DY¢,QÖ$5<Þò•90EΧ'“VQz2¥Vš=UsÕb#—ü‹‰²DY¢¬xþòYS¶Äœœ7Þ˜-·îˆÔ>5Ñì¦Úªæ¹à_üK” ÊeMFúnø¿þ¥€Öo*7-tG¤f©ejœÙAµR 5rÀ¿ø—k(Q–(ktœlûV³”©cΞÆí<"5èFàèrËÔ>5ÑÈÿâ_®¡DY¢¬Içd¼(|fÕtõ]uòvb<¶}æ?¤v¨)jÍr›Ô25ÎÈOÿâ_®¡DY¢¬ÉƒGWÕòMevÕ½u3xÂÕÛ¼µ# R nN¨f_޵|©6Í?˜6ð/þå @”%Ê.“ˆ„N-ÿêÁ)û%±KÎަ͜ÿ ®²«øË(ÌŽG ü‹¹†e‰²ÆìýɶΊ£Í_,b{mï_ö¨I‡<1ü!VåU‘Uêå²mþ¼µ£\í0ð/þý‡eˆ²Œ=Ó©¦lÉyç/Ë–u´åËÛ¡ÓÍÕ‰ñøÿþ ¨2ª˜*éê _pílΖôN§ ü‹‰²DY¢ìféÑ\|ØS»t¸éÓÕCÛYç/eñ«î¾–>ÿ!•KE;»6`nú¬"v©}Ä»ôhÞÀ¿ø—( @”%Ê®/£ ýîžúå'[šÚU÷¶nÑ©'‚葉ön[l4lŽ}H¥°÷ت7U•H…Z]7•QÅ[0ð/þ%Êe‰²›À“ç;'ã¶tÁ‡yƒ“5:ØøÉ÷î¢Èù†l™oÀ‘™LçÃà«mj³Ú²6®í«¿¯ŒÊ¥¢uN¶?}þØÀ¿ø—k Q–roOŸ?ѯöĆ\ò®ûlüø÷#à‰¶o¯ûV&n´tÕxûÛ¢£!«¾Ú‚6¢íhSÚš6øG‘àãëþC éÂØ°[%zö≀ñ/×¢ìö„ý.>œížJ¸{êËbÏ:~ÔPø‡:Ôô©žZqÙ»ÿNètyû5[¦ÄÞm ºÚÇbÛaØÕ2´-I Óò´H-U Ö²ÿlGÚlYì‚6®í«þÅ¿\Sˆ²…ý>ñllq@÷žiÌ…O_rï6òÚSÿ®n ªÛ«\ó¾:U9W½T¿ª?Χç^ÔgJ³å-ÕmÝõÎÞFO_«À©GbDFñ±Hr<ž™LIúý§þ§~H/ÐËôb½E·ÕÛë3Åú(} >V®¯Ðéëô¥új-à¯W¨-h#ÚŽ6¥­iƒÏ^<5ð/þåš@”%Êæ0/_½Ô ?Çú;'âáA»†YÕ~õVàØYÇO?Ò¬¹åÒ2´-I Óò´H-ut¡_ËÖâ à矞žž6Ö 'ªÍð/þ5áš@”%Êòç÷æL Îu¥Æ‚‘!g ¿ÅÓkstUµdKm邚Ċøå’ȹ‚ÐÉþ#W¼ûô8GÝ‘åDë×Gš>Ûßðáîºw$ý‹ž“¡ÿyÆþƒ^ —ÝôÑ[ôF½]Ò.hé(stUëÃõÑ!§¾N_:wjóoë¢È¡îïØ±ƒ4»^cuœt¨t´ðï¯ì× À CÁÕ³¹n‘Àçnƒª>{RÖqs;<Ô,ž6¤ìžïE~à!aS@Ê:nDxBز~;"x<ذƒRÖ÷"Hðl°) e7²<l HÙ%ß‹8ÁSÁ¦€”uÜH<°) eýv Tð<°) eͰïE®àa`S@Ê:nD žØ²¾é‚Ç€M)ë¸0x`S@Êúí@Æà`S@Êšaß‹˜ÁÕcS@Ê:n$ .l HY¿\76¤¬ö½È\46¤¬ã‘ãŠÁ¦€”õÛÔÁåbSÀJYß‹àÁµbS@Ê:n=.l HÙ ß‹øÁUbS@Ê:n@.l HY¿!\6¤¬ö½È!\6¤¬ãQäÊÀ¦€”õÛ4ÂeaS@Êšaß‹@Â5aS@Ê:nI.l HY¿ˆ%\ 6ì ”õ½H&\ 6¤¬ãáä:À¦€”õÛ|ÂE`SÀJYß‹ˆÂ`S@Ê:nRl HÙß‹ Â±cS@Ê:nUl HY¿ˆ«$¯ë³gÊVF†»ÙlÛ®c[Û¶mÛ6Žm®Q®A®ïÙ6~¾³¶w7çV›…¹d¸êôŽœÆ’‘’"Mœ«ˆÐÅÁI¾„íé§»º¦ì­£Ö—ƒ¦'½úûÚ[-ª«¯žIO“#¹Bnvho‘‡ÈF-/'í-4g'ËÓÇó ‹‚²0McësZjϪÜ}¬æ-ÏgÖgv÷v-ò'ÿ{ þئ e‘²ðÔìOêØýƒý¥ùÊB.Q÷“†Ô%øÂÀÅÑÞgxøZyñ‰äÄo?¾U^0>¢:;Dq]B@¾d¼î#_xicno÷'ÕìûŽEÊR)‹¿à7ÚÙÛ®.æý%‹2Êdº{†ÍÏÚÔ׿‘ÏegÚ47úŒÇm-TW7ÃÓÏöóüc‚à”8L—EYÊOéR2cFiÉjíy£³hñ”þª'TóGar Õä&¹ÓU´’'XrZcF¥OÉ4 ±2ΗGÙ’0C¤ðãßÓ3@sõŒZßô¶¨¯‘AÝoÃÕU2ÒKwuiâÜPÅÑX*ïìa¿R)‹ÝJ€cq}6Õ šÓ2®o°Ïðà«Ãžª+Ýúû#ÖW¤!IO’¶Ô§äŽ‚)PõÅšÑß~$L˜¤¯,ÊæùÇ©®žëëý}òµŸJO~ñ ñ|ÖŒ<Õ ‘?ë@Ê|Rö/pÄÞ›Uu¥kÿ¹ó请«þ)»cݲúš¡‹žlÿm{۶Ӷט´v>¯F»m 5"*qŒ„ĉQÁYA"“ˆ‡y™³ ƒŠ€¨8Ïx¿çóí¬Úwïãñr8ÀóÔ[{íw¯½öZ»ÎÎ/ïZïRtÏK1èúÓnËZr«ÃôÜ–´ÌÈxÛÓ×:é[œZŸ×œ^ÚZVÐVÖZœ&^ÄŠó=}Ó>1>5ºâP¾§©êË’sY-Wï?ºËߊ(KQEQDY¢l¿‰¢–©®£ÜT¶3s½%„sÙ›ó9¦ì&ÖF÷j:ªÁ~ƒÞª/Tæ5g ¶ŒéÐ{³?G'{fwÖÆ¤š#ˆÙbÒ5s(¢,EQEeÙÝöEµ];ƒiÃȬÅ3çékƒ |ã*B2LW ÚÑЙ &,Ç )ðóÏX÷ʼn…Ú~ )ðÁTd¬"æoE”¥(Š¢(¢,»›¢^²g¸ü|^LÙ~$:Ò’r2E™sšR‰¬¶[vcÊѲƒ;37ê2Ha…-Òb]¿{…¿9Q–¢(Š¢ˆ²ìnŠê¹/UcÏU$éÕB² #ûRW´›{Ct´Šö²”º8$gF—f G`2s¬ëüùóÛžêÞ½{/·æ'Ož\»víîÝç/l¾qãÆÍ›7m¬Îh-Qöå‹¢(Š¢ˆ²DYŠê¼Ý‘v*Ú'e…‚«M¦ÅÈÜ‹-p°ÛM_@ ‹î=˜·u³i±êvïW Dçí üͱ¨ŒŒ iÛÅ‹m¼¤¤¤þ£Fz–C}}ýŒ3à#1b„‹‹‹‘iº«W¯6l˜¸áiÓ¦µ´´X¹5 VüwìØaÅmÊ”)ð‰ˆˆ ÊREQQ–Ým«(ª¶½»¤*”Â69‘eû±«}¹Ž3“±Ém€f# Jí…ÒÞ/QÖÙÙYÕ è5zôèû÷ï+·«W¯†n ÕS§NY¬¹»»ûí·ß†u”=wîœø„……e)Š¢(Š(Ëî~Ž(êêK™õq¾_MsÅŽ©!Û±¤³‰Ž†Eȇ ·#¥–Œ‹_š[ÖéøžíUK”={öìúõëÅß"Ê"ô:|øpq8xð`kkkccãܹs¥ÄÇÇGyN:U ÝÜÜêêêÚÛÛqVJSµxw???œµ‚²Y IäFG¶Ì†ÄC'}Ôd¬/hNu¨ßD)Ç¿oß¾üüü9sæ@"Ô‰i½*7’¢S¬AÕ®5Åü[¬SµÅÇ:ÊúúúΞ=ÑTU‚JÄÍ:ÊŽ3F!«Vñññ‹/Þ°aƒºººJ%º'ÂÔb¸A˜~¬-¿sçŽÀðÊ•+(+)åDYŠ¢(Š"ʲ»)ÊšZ¯5©]aýÒVÇV„˜ÛJÑq£Ú˜ò`ßT7Á üm-Wä7gâĉð4Æ¥qU"_¡;£²²²l÷1¢¬¤MÒ5øÖ­[¸µHR:QiœäªÐÐPµøŒo½õÜæÏŸ¯]k¥O,Xp2VÛQV¤š—ŸŸO”¥(Š¢(¢,»›¢ôzÜý(¹6RÈ+eERmôÀ%:6òQ»ø`Ϥ®îÇ‚²¢]»v577—••©™·óæÍS3~7‚!>|˜““Öä³ÝÇF”Õ m0¢¬¶*LÆLc<ˆÄ¤ V°Š}tÄ- K[‘µX–ׂo7nÜxûöm]µQQQâ_]]C…²Vôeÿ—(Š¢(Š(ËªÖB¿¯By%{ª;ª:ËÑj.VG”ì•1Ýž¶º¦½ØAPVÑš„7|RŽDJ(™–Q«jäF¶£ldd¤T%÷Õ ³¦ÁÒ>U%F7`í™3g´ÛÞ†…{qH”}1QEQQ–ÝMQ—oµù*·ÓžlÜæ´Á„s´Ü¦´ÝYŸÉøF•í»v·³Qü¦›s[ZZ*•ÄÅÅáËhåpÿþý¥.¹ýTrhÝÇö´O6¢,Ö÷jWÒ„‡‡Ëtbhݺu² VE›6mÊËË;~üøÌ™3¥dìØ±?†'þED%Xß‹fe_LEQE”ewSTvC‚@ÎæÄ%Ç«Â+ÎÑŽU~ùʼnEè/N,,hNéG”ÎéÊŸÚ-m"X»ëôéÓwïÞ ŠSþ6ø¼d”E²(YÅ|fmÒ&8Ë)Щ0¹¨°°Py–U¸ªüóÏ?—–«ÜËDYŠ¢(вUDYv7E%ÕDÇb{ÒAŸÛ‰Vz¾àÐIoñœ†„þBYY«“¬)Åήrˆð¬1;B ˆ…ŠƒuŸ—޲@G© e¥Ä˜“–[ZZäoL™Ö¹ÅÆÆÊ)Dt±Ù¬ü½zõê2¤â着*¢,EQEYQ–ÝMQqåB5I§bˆyCÇk£dÜ‹Ïfô Êj7ÂQƒæi KJJ¶nÝ:iÒ$mKLmñy¹(‹œRR’9éN™L&9•™™ùèÑ#Ũ:7ìÍ#§ÜÝÝáùŠUÉSe)Š¢(J/¢,»›¢Â‹3›Leœ>Aºj_õ¥ÐlU[¡ýQVeVB2$©+K1×üTwïÞÕÎ@^µj•ø„„„ØâórQVµððáúS111rJR:áZ‹‘çK—.©0ÇnFi—ãê{‰(KQEQDYv7E¥×Åc¼’]s›ÓÉuCÓ¢ÌB³ —ªìŸÁ¸©©I[îææ&åj?›h}*‰©^½zUë†Í‡Ôv>ªÐ8Ëške)Š¢(ʲˆ²ìnŠªn+†Éh0‘膲…—ìÆk°éÄG­×šìŒ²9*¼D`)œ={¶”`‹ñÁÞ6ÆàgZZšm>–QvÙ²e¸ KjmDYãN?ˆýb"±b)ܲe‹”€Ò¥sž‰•ÂììlÀ­â(KQEQ/&¢,»›¢nÝ¿¾Ù´[B–£…øáeðIY‰Þ(+5jò63«Õ§À¿)S¦Ìš5 l©ÝÌÆ6Ë( g)|Q”íêêBÍꦀa´Y‘ùýû÷•'6æQÏ8zôhyF¹ª¾¾ž(KQEQ/,¢,»›¢2êã€.ùžB24Ú¼­x%ðbØ3í“£°P7íV¢:a?Ì@¶Ý'++K /_¾¬®š:uª•/X°§ŸÏ>|øùœtwtvvÖ.ÙU¡f ʰ‘ßXÎZGY<׳T†dÔO”¥(Š¢¨¡‚²ìnŠêê~¼-i¸%«1Y0†FÃË€WÂ3É¥ûI·}Pì';²¦¦¦ɱxoܸÍc±ÄhwüøqÄ3m÷éS]¿~†‘l977W-ˆ5 qZ쩃THzŒŒÊHUe‡¶e)Š¢(Š(;»›¢ ›Ó-{²=Èo4­íÎr—½y쉲Q–¢(Š¢^@DYv7ÅdªÞhZ;Q‰#Ö|ÐáP–"ÊREQQ–ÝMQó6ƒX²9»˜ö¿-»1/ÆÁÜ͇²Q–¢(Š¢ˆ²ìnŠ’…²e­Å„7šÖÌ­Åx1ðzôõo¶¢çÂ… m­š"ÊREQQ–ÝMQ²lÁÙlÂMk…çråÝpÐߊ(KQEQDYv7E”M>Cx£i-µî˜C£,E”¥(Š¢(¢,»›"ÊF–í'¼Ñ´mrh”¥ˆ²EQE”ewSDÙy[ o4­ÌÛêÐ(Ke)Š¢(Š(Ë²°œ¦Ta /^ GGYŠ(KQEQDYv7E” :é-C£áe"(¾Í’<==>|êÔ©®®.Ý%©©©/ ,,,¼yó¦õ;&$$ˆYY™uÏ'OžÀyãÆ“'OñTøÃÕÕµ¾¾ž(ûÿDQEQDYv7E”õJvÅ¿§M¤8^y%†ÊŽ7î«6lXnn®ö’E‹Y¿$22òY·{üøñðáÃÅmêÔ©VvãÆéÓ§?ëŸ|òɃˆ²EQE”ewSCeU†âßý¹›k:ªÉrCÙðà5WbH¡ìXH£Ñ£GK¹ÑQ#ÊNùJ–¾õÖ[¶Ðlbb¢ÖíòåËÝFŽ)>Æ.X°`×S-^¼X]»dÉ¢,EQEeÙÝÔPGY0L`¾'þØ—»©¢½ŒD74 C¿/g^¼ 8:(;fÌã)„=}||äAÞ~ûmÊ"ZkœŒéÊÖ#®ï¿ÿ¾8ˆvïÞmÑmâĉâ0kÖ,ÝŒå .nål|| e÷ìÙ#§š››]\\äoc'Lo–SµµµRbVôÞ({ôèÑÖÖV¢lÿ(KQQ–ÝMe…f%ëωš#d¼¡`h ·âXAY½Q£F©U£"ÁÈššå«sP@‹E§½DÙ÷Þ{hƒõ Æ¢ëׯÃóY"+‹rñw~~¾ŠÐj}v–r¬¿uüÍxDßþö·1zçÎÈÉìø(û?·Ji4±—Œ²EeÙÝQv¤tŸ”å{!^GØÄÁX ±Œ5%ކ²¢Ù³g#D‰¦›››” ’¸uvv‚*\³³³ Åc`•¸?q˯•EÔQêA¾%cÚ'³FÈ µeË•,*--MW[uuµœ:xð  +,Y´³¦ä·•+W:>ÊNš4éïÿþïuÿ—áç?ÿù† L&Àž(kW£e)Š"ʲ»)¢,,µî˜oªNmMü8¾êKRßà3 +CŒÆp£Ä1QqKclƒu€›šš´n*ù°u”[iHC¹è?ø€ÙöÍx°!­ñF ±âWJ0wZJòòò”h\ Ñ~ÇGYù»¼¼Ù•?øàƒ×^{MÊ•^ýuggçC‡É<ê>Q–F”¥(Š(Ë²’(¸ÀW°A‹Ðm†RvÜaˆ%˗âì;w´åJ Ve íÌ™3u—#ù“\îááÑ›}e¡‚‚‹ûÊÓHw Â’ÚK=z$1Ø3f¨BLÇgT¨ ÓÓÓ¥0""b  ¬.Á2²R!¤üãÿøOÿôOÅMôõ¯yª¶nÝš““ƒ!ÊÒhDYŠê#eÙÝQVÅîÂ<“]ÄmO¶GÒ©¢àÀ5 QFÊÁ•r‡EYµHUióæÍ‚²2Xnh¬>²Ÿ-QÙÅ-]X¦«0 ÁRëke1I¸¥¥` µqkY̶•B$…ŠÿJÇŽSH|ÿþ}ñD%Rèëë;QV«®®.œ===±Þøßøü•þøÿk†QÇnL'ÊÒˆ²E½|eÙÝQfn-Ž.òNY)Î;37šj"‰…Ë0d8A %ÊrGYL²r#l`#g©€‘ñ¸ÇiŸüýý¥þ¹sçZGY¥K—.·¢E0ö«Bæ*…R‚ ÌVš••%¡‘Wy lƃ\!!!€ù7ß|×öyâ(¢,(KQQ–ÝMeÅ*ÚËâ*û¥}"—`ï–˜òCܳÇÁ „a’v`> "†RÎ:>ÊG­ ¬J’¤PP ÛÀÊ©ùóç÷eQ Uša#ÊBÀoÉç¤S©ŒÊ£ 2î‹ÆH8ZídkÔ„ ä‡Ä}e±ORRRÒÆ‰£þîïþNG%&&ö6qQ–F”¥(Š(Ë²Êª/TbVêŽôµ¸Jì@ÞVSÍÑÊv3¹Ñq ÃAÁШaÂaà0|â08PVm]ƒìÁ:·ÊÊJ9ÿ£,„Èâ`#Ê*ú¦J R"IK°Ñ_å—Âö¹R‚}š(K#ÊRE”%ÊRTÏQVYJ]\`¾—G‡_-¼\þeQ@fC"1² C€Àpȸ`€0L,å0˜PVK Ssµn»wï–6äææöe§L™bû¾²PXX˜ÜwÞ¼yR‚dËÆMw”°ÊWü÷îÝ«2'¡r¹DmŸ«tëÖ-L™–K°àvp ¬VíííHµbÅ $Žú“?ùcâ¨mÛ¶!q”„¬‰²4¢,EQDYv7E”íùüU¬ºÔiý3ÖG”ìI«¯`œÖ~1Øòôú„ˆÒ½è|mC£f€V”ÅÔb…Ž*/.6z©â°7(‹5œR¿1ƒq¶F™™™AAAhÊE²ýŒ‡Õ–BF!‹³ºUÁØÎGÕ³ÿ~„aÁ7nÜÈÈÈ0VI›ÊêGåææ"qÔ»ï¾û¬ÄQQQQHE”¥e)Š"ʲ»)¢l-­þø¡“>_œX¤Pj“é£}9_€¦r›ÒH›}aùg2U†bñ&ÓbÕí †C¹ n”}ò䉚£ |EÄ\ª‹‹‹{‰²²÷TZZjã¾²h˜SœW­Z¥%[‹Â"[˜öØhe­Eɧbn÷JY!}«’c‡Ø„ê#ñè(‹€›E”ÅÆ¤ eEH}äææ†B%¡S-Z_ ‹Pç³¼½½¥B³n (]³fMGG‡nC Ì‚¶Òäõ•~”µ…&6«úŸÃßÑ6㱿£Fâ¨O?ýã‚LQÆÄQ8…ÄQp#ÊÒˆ²Ee‰²QöÅ,»1!Ù½9_hBµ’DwuxÉîŒÓ'^¨6®€=RºwGú:mOn:ñB²q•‡óšÓµÎ„²vc–ï¾}û@€çÏŸG´…]²]mjjêð/Ö‘J9QV'c‘8 Ycâ(„p‘8 á\¢,(KQQ–(Ke_̪;*ÓO'_Õ–0ʶ§¯AÛÃÕÌm%âOCW CÐ-èt‘®Óvf~zÔ|0«! «.!ÊRCeµðc-G!¤¯ME”¥e)Š"Êe)¢l¯ MæÇz«ù±Û–ä‚åµ?&ÕÆœÍ:슇Å#ãÁñøècÏ`þph‘jݱò¶R+õe)¢¬no$$ŽBÒc$Ž"ÊÒˆ²Ee‰²Qö嘹µ8³ÁW‚EžH·ëqüC¿y$8#Rà‡äFYÉEçòª.”tjÅ#àAð8x(<©{pt:Ý‚ÎA¡£ôõe)¢,7ã¡e)Š"ʲ»)¢¬Ã'³“j£Ÿ'7ÉΨFÛlZâ—öÉÞìÏAz‘eûW…¥ÖÇc±(ò!9Tr&4 CóÐH4 F³Ñx‹…‡Å#ãÁñøè;´(Kei4¢,EQDY¢,E”íÃdÚ¬Æ$‰^b(²"˜F& ÈXdH_D™cʃqùñªð5‘ Ä”º8ìRƒe¨HI•Ûœ~òL¶]-n9 òĽ*/”×tTÁðQˆSp€œq .Äå¨U¡BT‹Êq Ü·ÃMqk#CÍx<ÎWÑæ${Î&ÊRDY(KQQ–(KeûgZ2öSRbן£eB ·c}éö´5[—âAÄÐ4 CóÐH4 F³í:U˜(Ke‰²4¢,EQDYv7E”u|«¾PYÜ’ð)2K!ý/föF”ì +Þy¸p¦øbcÛƒy[1wO¶Ç®¬þë‘Ø7Õ ´"Óàó‹!d Ã8D!NÁnpÆ%¸—£T… Q-*Ç-p#Ü7Å­Ñ4Ãa»ˆ(Kei4¢,EQDY;ˆ(KeiDYŠ(K”¥e)Š"Êe)Š(K#ÊRDY(KQQ–(;PDeiDYŠ(K£e)Š"ÊÚEDYŠ(K#ÊRDY¢,(KQQ–(KQDYQ–"ÊÒhDYŠ¢ˆ²DYª/E”¥e)¢,Q–F”¥(Š(K”¥(¢,(Kei4¢,EQDÙ~Ÿ—"ÊÒˆ²Q–(K#ÊRE”ewSDY(ûäÉ“¶¶¶‹/Úâ|ýúõ»wïe"ÊÒ‚÷ºoóXšeÚׇw!ÊRE”ewSDY([__ÿöÛo6LžbøðáK—.½yó¦ÖgþüùcÆŒ .,,=z4Ü–-[F”5Š(Kýï#ñ¶¬üøƒ¾ºQ–¢(¢,»›"ÊÒhDÙØØØW  mhhPnãÆCáìÙ³å,Q¶D”%Êe)Š"ʲ»)¢,F”íìì”`,À5;;ûÞ½{˜c¼sçNyœñãÇcÖ±eES§Nõóó+(( ÊE”¥«=^_Ýy6­Oê'ÊRE”ewSDY(ëêê*-ojjÒ–HyBB‚e½½½™öÉ‘E”}tµðLuü­ 9/«Â;stž|)Uݽ”×\u¬Wm#ÊRE”ewSDY(;bÄ4{æÌ™ºr$’'òððТì¨Q£ºººˆ²Ž)¢lÂQ?§·FË`A#_ýf€×ª®ëÅrvÍŠßùÎko½þïWÎ¥ë.ÜúÙR9uïR>Ò5áïñã¾ûøZÑgkñ·Ô†šïÿÌ–fÌŸ; —ïñ[£-Œ Þ¢ª’¶!;Ô“›%DYŠ¢ˆ²D»!÷¼Q66#ÆÙåÃåë—ËapÜ!nغÁÆËiDÙH³g1å§fÍš¥EÙ¹sçr3ÇQvµëo_±¤q?zóþå“pˆÚ$%`Hí…Ý7Їÿë?¡|ò¤ã0.Ü[Üph¬-,ð‹¬•]¶h&JŒòÙ¼œ(KQQ–h7äž—"Ênݹ/ù?ýË?É¡ËÚe8ý£m¼œF”mll”f'''ÏŽ;§&Nœ¨EYd6&Ê: ˆ²iñ»dŒ&þôû5E‘¨ž*9ê<ï=)DpU&÷*FÕ^›Ÿ(åQ‡·)”U‘XœÅÚ×}Ÿ©hê‹¢lr\€\‹PmnòLW.Ë UÚ‹M)DYŠ¢lQ–ÝMQDYQVÔÚÚ*ÍFcÝ©ÇË)ìÁC”%Ê:¸!¬Š¹Á 0$fk˧OûÊ¡ËgRQ²à·ïÊáµóÊÍ壙(ö·-Á[…²~â$Vnn.sÔµ¶£,Ú Ô:â›Ãµ‰ ²÷Imѡۈ²EÙ$¢,»›¢ˆ²4¢¬¨»»[š½eËÝ©ÊÊJ9µyóf¢,QÖÁ­åT‚ оku§Šr èˆÃœ¤ýrzÀC«€X”,u~_JeåÝbW)GÞ&b .¼ZCj(#ʪ¶mød¾œÕÎ:žýþ/cüˆ²Eõƒˆ²DYŠ([Ò\œ\œ\ÑZÞËzª/TeVdž.x®[MGµ-([ÕV™nN«n¯êAcð8ie©æ–²çz5ÚRaÙÙÒ‚Ó'{Ö3¥gJð,ÏuƒOnm®tQÖv999¡Ù#GŽÔ%sÚ½{·oÞ¼GI¡Ùl–Íf¯8$ÊeÜ‚v*t»#ǸùœÚ¼q±”¸¯ùPJn¶gãPÖÓ>å¬e±¨Õ Ê"›±-(‹Sr¶ºðH?wQ–¢(¢,Q–"Ê7ýéØW,iÞâyâóþÜßHIRa¢öZp¦”¯ütãsŽY¬gÄÿ7"¿.O.A¤qÁÇó>`H#ÊBB˜:í ÝõÜçÚì¿Ùbctð¹Äm‰E·Ï|>S>‹W~„’7¿÷&hSÎemìZkñ)¦Ïž^ÙZ!>AÑR(Õe{¦'OžLš4I|E’§1cƨÃââb¢,QÖñ-ü !?!£<ÃÝÛ]JÞ,;gmÂ0Q<;Å6?;c¾.P çÆ«°­r;š tss“ö+h‘ßXë6~üx”»¸¸eMDYÅ«F\ľ²ÆScð:J*1f‡œíhL~!”µ=íSQf°\µÅ}‰.UÕÜÿž‚yÎvšxL”¥(Š(K”¥ˆ²À-y»0 X[޵ @/!7 ¥Ê!0OëE!V%öøû%¿×ú f™,õ Bá:¬U>¦“'ž…²Î˵µa^®1jj´ØÌXq¬j—æÊS€EweNõëß}¬«}v™ <ùÝÉ:”4e’,$¶½O~3g†Ä–…lUK0 YžW–Î*”E9ÕÙLûÔKuvvfffîÛ·Ïd2?ÑZ~ˆ²ÅRXhÞSu§f¼;Q²Ëtb1¬›ÿiS~ªÖÍöÊ^oÍT»Y¼ pš(kQE”%ÊRDYÏÝÛtJe³~ÿßrJàmé'Kå0µ4E-‹•’íý¤DM˜ÖT€áY¤JÂß yÇå_Ýí$PiDY\«Ëá,”P­¬òEÍZ“H¦šåëô#'ÜT]ŽX.*”PQ©GÅÁa]cæ8ÏÑ>»BÙŒòtåcKŸwåsªu·ö—S¡ñ‡µ(ë¹Ç“Œ)¢ìPFYµ¡ŽJï$¸kƒb}¬}•@•}‡²°Õ®¿Õµ­ýt¢øÈ]ˆ²öEQDY¢,E”]²j± -Æ?1¹‡ÉEIr¸æ‹ÕÚX%ÀR%vvùP;Kö½™ïÌ0¥§tz±ªVw»u[ÖQNcÃ$ 2'©¼ÇJ*ü C¬Ub+r)Y…¨Å|ö{ËY´¨©5Ì7–S˜q-Ojì%[úD½Q¡î­…ðÊÊÊ[¢,E”â(‹-[‡ÿë–]Œ|õ›oOü‘d*†Æ`ßÿõÏå,¶X1Û§(‹»£Ir-ù§ÿ¿¡£![¹VÖN¢(Š(K”¥ˆ²SgL5N‘;¹§ , •’ïþà»’ýHezí fkçÍ"PiLq„y¹Y•™pX¿e½”œ¬Ï×ÝÎe—ã· UÉ„ü,”ÅV@ÈEl1—•Ìé]¶æcZ—DtP1ÙØë}‚ˆëso5±Z”µ>»˜(Ke‡ˆ]jNÁÊH)a‚ñ­ 9FgSôqp]2Kw*þˆœºw)_[^$åHe½%c¾óÜÜ\æ¨L3–ÉÌJ m»®’%ÊRE”%ÊRDY‰ Z ~"›‘nö¬ŠÓ"“š‹lIº #q‘v#üÙ¶šÒuWèŒ(‹5«:7•\êÿõ ü]pA³ZíµÎ`fD_‘X–¿Š¡Å)„Rå÷Bºc‹†ÙÈÖQÖzŸH‰,»}Ö-0š(Ke‰²F{r³ä\íñ„£~ûý×å$í¿Ú’áPÍÐb›YPt]iÔ£«…Ì`lWQE”%ÊRDYÅ«àOãæ¨rJb˜°Â†B)Ap¤ªXmêr‹IÖ¥•B˜T®Ât\d6Ö%V†ôÂF”…´S‚eq,|,®>ÕÝJT†¶©Õ¼ÚÙÎàI壗#õ±ZAYë}¢Î¾û¦©Bµè·€I*f¢¬­¢ˆ²4Q–¢(¢,Q–"Ê*œCBY¼x1ðzð7g°Š(K£e)Š"ÊýÑýž×¸Ë?EÅ•‚Xªô{¦HRïjµ|‹ÅÈ'2ë"™Êw•¬NÎ˱»¬v!«DG•~ùÎÛ½jQVB£ ÃO<>Q´)*©’uK7§I‚(%¹\mܪhVç†Û­Ø°Ï¢›®¬ÁÚÞ'bØêVA¾2Q¡ŒÓ³eï¢Þ^ ¼x=ø«?Ãø”àB|Vˆ²4Q–¢†œˆ²öןÿùŸãy>|¨+§¨Âæ4Ëžl^’B‹ØëÕk¯r äzf`H̹u÷Úˆ¤Äˆ‚QhŒUbŸ,ÐݺËzRB¬‘)‘Ø­iœ„®m·cÙqÀËu›×â^H:…E¹Ý¥n¾˜ú[pú$J^ºå×åFDŸìÚŽeº(éSÃ+¯c_H7nܸyóæsÝîÝ»wñâEükK]]]—/_vÏ0>%¸Ÿ¢,F”¥¨!'¢¬ýõÿðxÞk×®éÊ)ª«û±,—ÍújŽ1†—AÊâõp„ߨ»wïÆ?Õõë×¥Äþš2e ž(""ÂâYüº®^½zذaòàøcÚ´i---:·ÇïÛ·oäÈ‘â;Öd2Y¿µ»»ûsûÓ×׋-²Ãáaq!>+DY(KQCNDYûëÕW_Åó677OQTF}¸%0ß“'FÃË€W/†ƒüÆÖ××K…………8´¿Î;'  3ž½zõê¨Q£^1@{êÔ)åÖÝÝ=sæL”ú¬[çåå)7+aÒÑ£GÃaÁ‚v#|Jp!>+DY(KQCNDYûËÉÉéYÿHQ·î_ßlZ t‰­!ÅÑðàeÀ+ƒ(ûàÁƒÄÄD€¢”:uªœuss«««koo÷ññ‘Är•›ŸŸŸNž<¹   ³³qfà®@ïíÛ·-Æ?GŒae1÷¸¬¬ `œµÊbp!>+DY(KQCNDYûKþK+**ÊâYŠªn+’MD3N›ÈrCÙ2Lò&à•°ÿo,ÖŽb qPXˆÀ)°Ó¦úm<µ3Ÿ…²f³YN­Y³F[¾dÉ)Çìh™#=|øpŽ?þþýûÊ ?Ëâ–‘‘alÃŒ3ä¬Åþ‚Ùe¥Íø¬ei4¢,E 9eí¯?þÏëååõ,ŠJ¯‹Àx%»æ6§“膦aèñà5ÀË`‡Ÿx$Â8q"Ð€Š¶ˆUÊUHoooLÇUÀ†uj̘1ÕÕÕjé鯵qKÔ†¹¶×¯„Ðëì§jjjRx,þÖQÖÕÕUNé²=ajñâ§Âôc"+n™™™º¨/ nEEEºšƒ‚‚$`»|ùr‹ý‰Xq¿ ,>%¸Ÿ¢,F”¥¨!'¢¬ýåïïÿÜÿÊ¡¨ðâ`Ì&ÓG§O놚aÐ1ôxðàe°ÊŠ›Édj.fÏÂÍÅì\Éד¢²„m6'.9^NÞ¬†ÁÅËXcÐ1ôý‚²Ó§O·¸Kªâ%#Ê)¥$55U{á¥K—f?–ªÚZ¿A¶£,î"å¢M›6a¥.¸Tmºƒ&ôÂS¬gÚS}úé§jÛP±Ô‰'’BYôëh(‹®ÂÛCDYQ–¢(¢,QvΜ9xäíÛ·ÛâLQ—oµ)Þ)³'Û#·)à7¸2<¥aXe|1Ðn z¡,ˆNw*99YES(«¾‚{YoP¶´´TÊUÛÔ­Uòa)WnÈ8¥­a×®]Rîéé)(.S”7lØ€CDY|Dp>(DYšŒ(KQQ–({ðàA<ò;ï¼cû%UÕZè—ê&ÀQ²§º£’8Эº£ C)cŠÁÅËX÷#ʪ5«Æ¤Gt5¢,–›J0³÷õ÷e[ZZ¤«du—ÄÆÆÊ)$"Ô”ksM »Šž‡ˆ'«%»e_I%I–Cd{êG”ÅGWáƒB”¥ÙɈ²Ee‰²òŸ\Xã$ù3mE=î~”\)ä㕲"©6š48p ÇA”Ñİbp1Äý޲{ZYåTcc£eU]K[{YoPöÑ£GR¾zõjÝ%Ø›GN¹»»ãp„ øÛÉÉIÎs #/”Êe]{öìé/”E—ÊBY|Pˆ²4Q–¢ˆ²DYû ÿ…§F’Ͻ¢Z¯5ŸôòK[[ÂŒP+·† '#ˆ¡Ä€ÊÈ:Ê"ê¨;…8ªœ+QVmm a›)Qé ¦>UMMõ÷eC"±í†ƒdr’³Æía¥LKaZg+‡hC¡,> Èí'¢,(KQQ–(+«ËdEõ@Åg3w¤¯ ‰øf5$Ù0@Á>jÈ0|DÛGÜnûÊ޿ߨDÖ_cc]n¤Í›7k/tqq‘rd$¶±þ^¢¬¤!m^½zÕâ"X³ÙŒCD†å0;;[ëVYY‰BëÛ´b6¯ƒ¬••yÝø”eiv5¢,EQDY¢,’mÊã‡ö¸Šªë0GïÔÐÑÚc•¡íeäFÇ1 C£† C†“t4”•˜äÝ»wQˆ|¿Ë—/—B œnI* ©k†,..–B¬/7ìk{ý¢ÐÐÐ1OUUUõB(ÛÔÔ$§&Mš„H¬‚WÑ0)”Üä,‘U[èüùó¸£<ØÛÁQ™]ŒO Q–F#ÊRQ–(koÉæ‡èe=uíÎåÌú8•Ê#áÃÂíÙ)ÄÈþ5 AHÁv ‡Œ‹oê* ÓÕ;@,‘ƒ¢¬ÁR!@Ù0:TêTë]%¾*L(Xû¢õûøø¨|K¶£¬hݺurV"À#GŽT-A–ã‚TCBBTÂf<ÕFFFFGGãL<Ÿat¯€w¿½RDYQ–¢(¢,Q;ï÷ݳÕp© »¼ìÉr²óI]ZRw¬¢ÝÜx£¡ÑèLt©¶‡÷f–RÙx©Z ÄCÙ^Èõó3,ÛÉâóA”¥Ñˆ²EeûMþçŽÇÏÉÉé»»PÔ{WÌ-¹Ñeû½’—k¡kW–{”90§)Õv~£¡»Ðiè:mOz%»Æ”í/?ŸwãÞÕ¾G¢,?ÃøXÀ|>ˆ²4Q–¢(¢l »ùãñ'Ožl¯RÜ–¶9§á„Ú™VÌ#Á)v±£¶<Í8m*k-&²Š¡+2Lq!èt:JÛoèFtfÛµ3ö;¢,?ÃøXÀüM”¥Ñˆ²EeûSXröÿð訨({Þ—¢<¾-aLÕa;3×+6S¶-ÉeoÎç%{k£òÏdÖtTpÅcâañÈxp<>:ÁØ3è.tZ]GùÃÇÚýQ ÊFDDôì.v¨ŸŸa|&à†O>DY(KQQ¶ÿ%;O ùg5€¢>~€hmÙ¹l@Ú¡|ÏmIËŒ·=}Í¡“>±Á©õñyÍ饭E\ñx< †´„ôËôL¬/kÉA=êz0~â)#ÉOþ&ÊÒhDYŠ¢ˆ²!'''tÂÚµk¤=uýnç鋘=U¶oWæ#ã‰y&/Ç®3ò¶|Y]dª‰Äü䂳ÙåmeŽ«hƒ&¡ah‰¦¢Áhö³žU¶ŽÇG'ð'žr1Â>øXÈ!Q–F#ÊRE”uÉæ ›ÿ‰¢w=j»~¹£’j""Šöç|.›ýX±/N,Bj_¤G Ê÷ -ò/ÙYº?Úˆå¸Ø·æDMdRmtjݱôÓ'²“r›ÒNžÉ–6%ç Ìm%•íæšŽ*þÀ! q pƒ3.Aê`\~¢æªB…¨•ã¸n‡›âÖh€õâð x< ø¨ë!â)#Éö$›·ei4¢,EQDYÇÒŠ+Ðo¼ñ†lèø¢¨î'ÝHØÛv­¹î‚¹øl6³+<\à»+óÓ­IƒûÝÐ 4MBÃÐ<4MÅY²;¬hGðIïƒy›±+2*mOûÄ;ÙuKâÒÏÂðö¹AáÎŒõp€[ÈIo\‚ q9*I¬K=•Y •ã¥ç²p;Üôÿ²wœëkaÇŸÁpÀ@ ‚@00@a{ &‚@ç À‚À°@„€KWâ‚Aç²Ü×ÿºüþÕ¾{_ÏÙóüù×ϵLGÊÆqüÖO‹IY>R)‹ªª,Ë‘4M  õÒ4˲ªª2€”}[Zkiäyn-–ç¹4´ÖæÍ@Ê"IQJ•eiZ P–¥RJD’$1€”ýQ‰H·Û=¦eÇã±ÛíŠHE²$q]·m5 t¬ëº"ù8²FÏÙl{^óØÑhd>¤,³Y¥T¶@{ž”Rß3€”å¿Ù6\èîî|×ÿ±²ì4nÄqüx<Ì<8Ž¥ñUûŠ e¡µ¶,KDƒÁ~¿7_°ßX–õ…÷c eQU•çyÒ˜Ïçðáæó¹4<Ï«ªÊ€oMYÌf3iôûý,Ë àeYÖï÷¥1›Í øú”EQ¯ñìx<æ½1|Ö‹âñxüÆEa@{RëõÚqi„a¸ÛíÌìv»0 ¥á8Îz½6 …)‹ûýž$‰mÛÒð}»ÝÖumÞ ®ëívëû¾4lÛN’ä~¿Ðæ”Åõz],NGJ©Éd’çùï=ÛœØÉó|2™(¥¤Ñét‹Åõz5€”Å‹Öz8Ê?”Ra¦iz8 àG‡4MÃ0|ìÓp8ü·C;€”ÅétZ.—¯½P¯¬õ}?ŽãÕj•eYY–çóùv»Õuý_‡·À¸µ®ëÛív>ŸË²Ì²lµZÅqìûþ3__<Ï[.—§ÓÉü"@Êâr¹h­£(êõzò#½^/Š"­õår1ÿ eùŸ¶(ŠÍf3Nƒ ð<Ïu]ÇqlÛ¶,K~À²,Û¶Çq]×ó¼ ¦Óéf³)Š‚ÿ`ÿfï b‰¢8ŒÿUˆ ¥ 0BI’ **P)(@1"T0Š*%¨€AH…k,–µ ç=wððž½w½ï`÷sï8ø3) àòòRREæúûû%ÝÞÞZÍñÄwffFÎÕÕ•Õ@ʨ®÷8::2°»»+innÎ|ÀÊÊŠœƒƒ« €”ððð ©­­Í<Áçç§¤æææJ¥b>`kkKÎÆÆ†…²¦§§%Åqlþ`hhÈïWÊY\\42RÀÛÛ›œŸŸƒ?ûûû’fgg þÜÜÜ455Iš˜˜(•JÂDÊX]]•´¼¼lðêëëKRCCC±X4øóôôÔÑÑ!i``€-8„ˆ”Ïç«wP¯¯¯߆‡‡%]\\¼úøøèíí•ÔÝÝýüül (¤,€íííê[JC’$‘499i¾¡P(ŒŽŽJjii¹»»³pR@gg§¤4M-Èårr²,³`aaAÎÙÙ™…²NOO%õõõY00>>.éøøØÂ€õõu9;;;æ eüŽØÐ®›prr"illÌ‚½½=9kkkæ eÜßßKêêê² Ë²w#áüü\Îüü¼Õ eý—Ø¿“¦ikk«¤‘‘‘ZüÌ HY@HÙ¿öòòÒÓÓ#)Š¢÷÷w  eÁ§é`ê¿¿¿%µ··?>>Zø) µ˜úr¹<55%©±±ñúúÚê eÁ¡S¿´´$'I« €”‡ZLýææ¦œ8ŽÍ3@Êú‡_ìD«]Ǹ /’‹T0ÂL"1Q$ *¾ÒÕTi_‚  O–T’J U©’JRµ²ZU«ÉV=ßߎÝöîýºû¶Üx~¸ÎÎÎ9ç=ïûpÏïìÙú¢Ð …B^¯·£££´´4+++77×f³õôôÌÎξ½½Q~¿¿;Æää$%g``múúúPŽD"N§“{=<<˜ïÓ'íííV«UÓ´ììl³Ù\SS³¸¸H_N8nmmÅ&þèèˆ q»Ýh6==Mߊûûû¿bƒAJÎèèh·xîgooïõõ• A8q—µµ5Òãðð°ÛŽŸÏ×ý9þg6,/ynnNTVár¹x¢ÚÚZA!ÓˆÊ š§§§pWSÊÊÊà3ñÒËõ0^¶ÜD¶¶¶¸MII ^>>>ªÑHºº:¼›““CÿÅÈÈÿD ¯¯¯)c>Îs•——óùEFAATVÐ\__WBUUUWW—Ãá€Q°1²!ìîîª.v»ë———ItçG©¬»¥¬²+++jtù; j Œ——Ê ûûû<‹ÏçÓUYQÙÂ_ùpD’ì“ü©©©øf@À@e–ÙIÀe¸Ý¢†ýP°ùcU–ãÙét~;•óóó|ýEEE$‚ BÚ•$4±ÑD™©®®…BÇùù¹RxB$QÉÀ\ÙØØHzh卿‰*›ŸŸFSSY¾ÈÌññ1Åq{{‹ÔhllìëUVT–]‘ÀÉBoo¯ñ¡•••¦8††† Tvaa~‡ŠŠ ŽJ+¢²àä+//3jš¶±±A‚ ‚ ¤QYABfÅ/ÛÚÚ’e~²ƒdö~HÅ¿œC¨›]l³Ù$¨,p¹\)¨l8æîH"5ðÌææfJàýýf~uu•i•E2ò±U–›ùý~2ÂøšSÚÏ™á౦KeE‰§Á`ßr8WŽÊâã&@ÈÓ®²1šÊ>==áN~r–H$òõÿ#`^³ÙŒIüø‘ίˆ ‚ ‚ *+HhÞÜܨ¼bìŒ) ›››ÜLÓ4UÙÒÒ•KKKɲ‹yÿªT–·æU.Ÿý®Ê*­êïï'=¬V+lJ}Wù§ÅbɨÅB?â}êòòògŒÕÕÕ?pÅõ;;;<¸ºxP¿½½Í*Ë‹ä½;ß+üŽ+\4Qe½^/TMåÊÚíÿ²wZ|k(€¸B€ ¢p*¢[‘–’*QRÕFW’ª-RµŠ¨E]H  Üûø¿#¢Ðô¡`nݺ•íaíFäîâ-xÏpïÛ·èzœ—þ¼{÷®öo åtaf(¹öyAÙC‡µ™‡/]º}þü™±‹×ÜÅEY@‘Ôbq»B6lp¶×(KÊ4.ïÞ½ñV8q‚í6 Æã2\^0Ö^ï™3ghïG¼öúòåË®]»Dæ†j¶+¨×{½ÿþÆq–™™™Åú‹°sçÎr­A*•J¥R©yP¢l*§æÃ‡«i³ôîJ¼üPŽ-SSSµ»8è˨‘( w½4+ÌP”%T¨ÛÙµ»ÝzðàÁŠJÑ=Ù,¹6 ãa.c°r¬üDÙúSoŽ(øÑØ(nPŸ7¡§»Ý€Ôh]÷Î¥#çC}ÒyAY†»m|ì!g^³úÚí"¢,qu­õõ 7¢,þ|¯¢tVÇ‘ã Rkvv–û÷<É&ynœ?Ôt…`µs›CØ‹ˆ²èàÁƒqvžªÌÃáR©T*•J%ʦrjR)'^“¦¥{êÍDË á‘µv‡“¶FYÞîÞ½;Þ>zôhèZYBRe” §1hñëׯ6‹cüô§“ðþdüºÄNݨi”¥,[(ÄB leäˆÍã¥Kâ g,Q6D’íÁ ä¶mÛõy(Êjùf9/£#¹jZ¾% Håξ~ýz¶Œ_+{÷îÝ8Hi‰Èv|4==Í[œÏÏ\¯k”øÝ«¥{<Ê=zÔÓCÖ“O8Æ…DVcP–q‰#ß¼y§÷ïß¿_¼xÁ´÷îµf€8W¬Eç5ÍÂ;àC²dÑŒ º Ø,å*Ê ´|éœáÿ[$:u*:päÈ‘±ÇJ¥R©T*•(›Ê©yàÀxk±{œŠÑs¬qù%«ÝÅØ’ÛPVZW€„A(KXZh,ÃÃÏe,Á¦Ö9EMHzlBÝþ(Û½V–+*}Â0­§eÏ"pðþ}žeš:ŠuΪiâí%…ÂäýQ–›pàOmÞ¼Ù1ŒëRIž7€ á…Ö»Þ¿U|Æ£,Ö÷8 f„Ài-ıªœe±׋ÁÚ82O.ÚÖÊR99®ÂœÀAþ„»}¢$Ê@^:®^½}`Â:P*•J¥R©DÙTNMêîÄkRuïB¬\þj¯µA>F®ÚP¶<àáÇû£¬6c¬°„vk³e …øPÇeÆ[Eø.'󅲆Å,Õk®¬e៶,YøŠû÷y”Õî Š·ÜÌÛÖO1Æ×•­ÉÊ…tÀ tˆZMÑ«í¢ ì­[·çÃ÷ïß¹?èãÇ£¬–Ðp•Hÿû—ÚÒ>н7ú®%Qô]jˆl¯ZµŠnlٲŋ¬T*•J¥R‰²©œšº(-lÓ&ãQØ8Ëíü@HˆˆTFñ•n”å§¹QJ ÛBY$`—%íX+U–¿é¯_¿Þ–!»ò¼ ¬Èª0ŽzöeËú*¼iýû<eëKz!Q–œqÞË—/פ=(*Ë8*X”\YÆuëe®ùõÁÂ9¡²~liw;#þŸ&®‰²Îö¶Ž1®.Ñ7¾Ú"ÚPÖÇFÌ¢£*¢µ/§=Ï –à_¾8k×®¥'ëÖ­s}ø0¥R©T*•J”MåÔ âõÓ§O»w1~;§$ KFcû³gÏtË(‹0ÐÆFÌ–Z‡¢lß&…Ðê®#É ä0è@Y‚oýQÖ³t£,.è6F=vìXÏ>w£,€T£,æÞ6”5‰—‘aåÍ‘iŸÈ+Öh.%»¢SôgáÓ>ÑIÛGY¾;¢¬éµê\8½Z×(KÄuE» ó–({ÿþý¥ù'Dan_³fÍ«W¯ïŸJ¥R©T*Q6•S“|3ñš5Ýõ!-0S¯\5ª¦»˜å‘¼î@YEjÖØ~ñâÅn”µ°¤´#» ‰y]ñXã (˪Ôþ(ë¾Ý(Ëëâ±æ‚êÙç”ýùó'k”±:PV„æÙÄœfŸ>}²t>Ûnxë¢ÿ¨Ô]x”%–nÆ£,Œ*Ê–¡ø·oßž={ÖµÄÑC|é(‹s!ÚÆÿnƒ¸ôQÖÿ7bÍðÊ•+ûa;§R©T*•J”MåÔĽ8d¢ÝF‘%8Ú\»v­þ”Bšñ+œ|ª{¢,¡TàÇ;²})ƒ|mkz5-kÜ¥ÿm¦YpN”5©U•×j>Q¶F2Û¿Ï¢¬™¢]h:Ê2õŠ_y~<Ê"r/ÏiÀó‹82xêö2åpeÏ;ר1fÝ?ÿJÚPp­ŸSˆ²¼ef¢ru:«FÉë«M½eu€×uk™iqLVÞ. ”U{öì‰^]¹reØž©T*•J¥eS95õC”÷hÌÔb)W~4× 0'G¡”Ÿæ=Q½yó†íªeõ3Ÿ¹à*ʉaI-]ýËeÍVí7ºR©T*•J%ʦrj laæ Œ¹wï+Ù@ x†0 H¶[¶-Ÿpüì®CöAY ¡Êœæššš ö3c° zM‡‹M7¶zGB#~fWP¤Æª¯_¿ ‚(öJpåÓØBiœ‰Q–K°ÐÎ;wb#5x†öÙP^œš›c¶á PÖÒ¯ÜF:?Ç>e-l¹±D"k ŸFYb§N¦Þ.;”Ed;3÷ø€ÝR©T*•J%ʦrjŒˆY-·.£RGý->eù”St£lm µo°À€x ÔÉ$úTi„:–RBÇ/i ºDYÃ#@˜ ¬g)¯šìJCûÌ­®û<ÊšSÚ¥+åßñ(k†j„]·šn-K°š7{ÁP1âì⣇rèL²Qª‡OmækQVø´ ß;ß;ÌѼÇå·|ePnÈC(Å凲UYÝíÛ·Ø-•J¥R©T¢l*§&sáÂ…Æ2­à„¿’ÛôáÃaÏq?º°­Ö‹­ž(‹¨\²cÇŽº«ô¨6T+R²šÔ6z¡Óðæ-ÛlÚ´É Æ%@r£ÊB©?~ühÌíêS‚iåâOÖaÆêbŸ ísí¸öîáh "=þ|´!ÞÛˆ²„ÜEY)(*»(`‰Ñ/y²{)¬+EkјŒóÆs‡ŽcFJj±_@i±î/¢ôCQ1úÁŠ v ÷’çTW"t\—÷ïéÓ§ã{d3Bú¶QtÒÇÁÒŒ¦®cHG®"ãšÞ˜þœì2Äİ"ƒîmf¨•;Ðmä࡞­Ç™@¬™$ŠKg¾}û6²ÏÄñ€.ÚÀQ’Çv…‚€dn‚'ýÛŠo÷–çQúµ,¦Ðëׯ±tL!Úø ¬Ñ#4],ù¥‡Uë5ý¡ôÃÔ]ýŸ½;€h.  <5@B1(ˆP…BQ+, … £@"…Jh(@ P°` ÷¿Þzï}¸9çÊ©ÍMÑo„ÇÇÇþþþxÈøƒÀ”Ý€¿Ï­o4ãããñœ]]]ÉSÕ€) ¾€[ÿóóS©T~_9LYHE7·~uuµØÛÛ €) º‘àÖÿ¾Ó»¹¹St#À­?<<,$–——`ÊBÈ¥6×××Åb1ž¼\.·Z­˜²¨fÞ!…îîîzzzâáGFF^__`ÊB¶5›ÍÿÿÏ©×ë욘˜ˆ)_\\2êååehh(¦ÜÛÛ{S2¬Z­þÿ\b Óö÷÷cÐóóóìúúúšžžŽAwttÜÜÜÀ”…¬*•Jñ Ôjµ@¦5Bâãã#iKKK…ÄééiLYÈž“““Øÿááá@ÌÌÌĸY·±±QHlooÀ”…Œ‰#6ö?Ú@Ÿggg9°³³SH¬¯¯À”…̨Õj±ü¥R)Íf³xäÀÙÙY!±¸¸S²¡\.ÇòW«Õ3B?88¹á/V1ô©©©ÏÏϘ²©õz=6¿X,6›Í@nœŸŸÇÜ'''¹ñððÐ××s|~~€)›^°²²›¿¶¶È“ïïï¶¶¶ýÛÛ[ 7bÜ£££1÷îîîÛÛÛ˜²©†wYžžž9³°°£ßÝÝ äI«Õš››‹Ñ···_]]À”MØÚÚŠµ¯T*ü¹¼¼Œéòúq ß—S6•à{wÑZÇqüŽBjH‘ŪR¡‚@A)@0 6A…•J« RD ÒH4£,´†U)XÐÄÿý;¹ôºí^°Úu¾Àã ¿Ùs—Ë¥Ù'“Iý Ó45€ûû{±„Ãaâ?i `ÊÿŠ m¾··Wì £££Ú€¾;*¶„õõuÃ211!€)ûO:::´ùíím]h===»ÚÝÝ5,###ïïå 8<<ÔàÝn·ÀÞªªª´„l6+v…ÓÓÓššš‹Ó///˜²e Ôà#‘ˆØ€–°²²"6†l6ÛÖÖ¦%x<žL&#€)[†€t:­µWTTäóy±7i boÈårýýýƒÃá899À”-7€ßï×Úgff8 …êêjíáúúš£€×ë5·è`ÊåæùùÙ°ÜÞÞrPãããÚC8æ( ¦¦¦ K4À”ÊÄâ⢦îóù°$ M¢¥¥EËÚÚša …B˜²À+ N§SSO¥RüR[[«U\^^ `ÙÚÚ2,~¿_SøY±XL;ïëëà“`0¨aÌÏÏ ðK<7MSÃâq0eŸÔÜܬïíí ðÉÙÙ™†ÑØØ(À'õõõÚFWW×Ãæ,ðýö÷÷5r]³ü¦¡¡Aó8??à“ÇÇÇîînmC7­.[LYà›}<‹ÅøÍÜÜœæ1==-ÿ¼¾¾k¦iÆãqLÙo¤R)-Üáp¼½½ ðÕ_Iµºº:ù  Ëææ¦¦ì÷|>Ÿ¾°° EMMMI2™”¯¡PȰ¬®® `Ê¥vwwgXžžž¤`iiI#™œœ”"€h4jX‚Á ¦,PR³³³}¸ººÒN\.—ììì¯×+€) ”H>Ÿ¯¬¬Ô¼Óé´üÐÞÞ®©Kq@"‘p:Tçr9ÀÞ˜²@ID"m{``@þX^^ÖZÆÆÆä€L&ãñx´–ÖÖÖ››ÀƘ²@I¸ÝîÿØ»ȶÚ(ãw²²dX°m"Ë“ÍÈbÆd€lÄ[Ъ–R)I•6%TJªZB‹¶%¥TÊ­’*J¥4ÎwÜ Ió~Húü<È_ÞãjÛ+++\ekkKkÑ?Üä*€mÛ¡PHƒñx<ÕjU`Ê2e³WmOŸ>•îÏž=ÓfÊå²\èt:±XÌr‹EàFbÊš¼zõJÃÎårtgllL›ùöí›ÝI&“–#“É7 SÖ<`}}]«~ðà]ÛÛÛÓlîÝ»wyy)@wÒé´åH¥RÀM”5ø÷ðïÏŸ?ô" j9KKKt-›ÍZŽD"!Ü LYó€ËaÛ¶½˜œœÔr¾|ù"@/J¥’ËåÒx¢Ñh»Ý†SÖ<àׯ_šô÷ïßèÑÁÁÆsûöíóószQ«Õ¼^¯öšÍ¦ ?˜²€9'''wîÜѤ766¤wÀ›7o´ŸB¡ =†ßï×~|>_½^—aS0fttT{ŽD"r-Àôô´&ôéÓ'épzz‡5!·Û]©Td¨À”Œyüø±ö|í_€mÛ–C7‰\ Ç-G>Ÿ—áS0c~~^c~þü¹}x÷î†477'×üþýÛrŒË€) ˜ñâÅ ú7;;«!}øðA€>舵:keÀ” X]]Õ’=z$@Z­–å8>> ù|ÞrÄãq:0e>~ü¨%ŒŒзH$¢9år9úS©TÜn·æ‡9À ¦,`Àæææ¿Ï¶Z-é°°° E½}ûVúÔëõ'OžhQ~¿¿ÑhC) ðãÇÍøçÏŸ˜pvvvëÖ-êððPú4›Í@  Ey½ÞZ­&0e™²ÀÑÑ‘åØÞÞÀX,¦QMMM `B»ÝŽF£•Ëå*•JÀ cÊüýûWþüù³æ,..jW¯_¿ÀœD"a9²Ù¬0°˜²€>Ô†×ÖÖ0çâââîÝ»šÖþþ¾æ¤R)Ë‘N§€Ä” ˜™™Ñ€ƒÁ ¦}ýúU뚘˜À¨L&c9’ɤ0h˜²€~¿_. ˜¶¼¼¬u½|ùRÓŠÅ¢¥œãˆN§# ¦,`@¹\Öz}>Ÿÿû÷ïkc»»»˜V­V= …lÛS0àýû÷¼ÿü½;àh(Œâ0~Ó ¥’P–V‘)4ˆ$–¨FJÒ¨°¢V ‘a(@C 2!‹™ŒR¤P)¡€’JÇí3¼ç^<¿ðøÃ1w/Œ—Åb1RÀ„ëëë@ óûýÅb‘ }œ²Ú€óós™nYYÙûû;5 Ááá¡Ì¬½½†àõõ5 ÊÌ|>ßññ1Aú8eUápX¦;??O UYY)K3ú‹ …,[*•¢@§, äùùÙ²ÝÝÝQFMMMÉÒVVVHa"‘ˆe‹ÇãÔèã”4,--Én‡‡‡Ia²Ù¬Œ-Â4Äb1ËF©PÅ) (øúúòù|²Û““j@Amm­ìíâ₦a{{Û²…ÃajôpÊ ‰„Œ¶··—Ð1;;ËeP“Éd<Ln`` T* €SVÐÜÜ,£Ýßß'…äóy™\cc#)tàì쬮®NV×ÙÙùøøHèNYÀ€t:-‹mjj"…&Ô××Ëð …)tàááAîXYÜ´rÙŠ€S0àÿÆ­­-Rh‚ onnŽjðññÑßß/Ãóx<™L† Pœ²€…BAæZ^^þùùI M8==ýÿ}Œpä m±³³C €yœ²€###2×ÅÅERèƒßï—ùår9R(C4µlëëëÔ˜Ä) poÙžžž¨§^3ž™™!…>ÄãqˉD¨0€S0ü±âØØ)àˆËËKY`MM )àˆÝÝ]Ë …¨€SÖ T*y½^Ùªƒÿä ´¶¶ÊŽŽHád³YŸÏ'# ƒoooNYW677e¨}}}¤pÖÖÖd‡¤p ŠÅâÿgÛ---777pʺÐÐÐ C=88 …ƒpuu%;¬¨¨ …ƒðòòÒÓÓ#S¬ªªÊçópʺJ¥d¥mmm¤p:::dÎ>ò |Z¶½½=‚8eÝèîî–•&“IR8²ÆÑÑQR8ÓÓÓ–-‘HPÀ)ë.@.—“‰VWWÿþþRÃq¸½½•Az½ÞŸŸj¸ßo‹ååej8e]’‰®®®’Â%ÐÕÕ%›L§Ó¤p$“IË699I ü±w‡0ÊÃ`†‹ÛâÞ´^¡°xÞ oÀ›aÐóªxƒBÏ«zµŸpÉ%N\™Ï#PŸiÈÛð!6«ìk¨µ^.—ý~¿Z­rÎßo ?Œ?˜y‰™ÛíöõÀ§w=ûßiÐŒ ®×ëÙlBH)ùNÍh°ÊN])%üo±X¼åuoæ|>¿ëÙsÎÇãq š1£A šÑ ðZ¬²Ïkš&¥´Ýn»®+¥¸yÝŸ¡9çÓé¤Aø+ ‚«ì¤¸ÝxK}ßo6›¦iÂCJIƒð ‚«ìä”R–Ëeáp8ŒðŽj­]×Å'h4Xe§e·Û…‡cß÷# AÐ |³ÊNÍ0 _Bßµm[káóÜCÐ üBƒ AÀ*;))¥ãõzá#µm;ŸÏI@ƒ AÐ `•”ú0~šìÝ1@Ñ%7ÊQr…Ü,Wë¥t1Åš ï¬RøÑd½÷]hþìAƒ AÀ( ‹÷:ZÅáÈ ‚QÖ( Vq;¬@ƒp7 ¾¾FÙ?ŽõÇ{/Uü÷¼œAƒ A£,eëí÷4Ž1.Ÿ‚;÷4 >e·$Ø9l”ÝbåÞ—æå§ ‚£,eˬµö×Èï4Œ²`”­ßZW‡e?h4eÁ([{ò!. ³¥ òÉÌ9ãN ‚AƒFY0Êžq”ˆÅ;šm­i44Ê‚Q8Fü{ã²xÐ hðù£ì›½7ªêúÖóÿ«¼þåUcuÞ1üÃñÊ[/wX/õ,ëgå]Ë››—çÍÍMnÊŠ7V¼ÉOc››Ø7 Š 6 Ø!Š€Â¡?ô8À¡¤QéľïG}ƒ92ÇÎÙÜ?Úsà›c{íµ×^{­óí¹¿µæš«ººzýúõ»ví’ü¼<:tÈçÚÜn·¯X±.$ÁÁÁrpêÔ)ßzŠ¬ï•»wïG¤²£& ¤g̘Á¦ PˆA …ôf*{âÄ øÁÈ¡¿¿??üðCßjð¤¤$T[dÞ¼yHY¾|9þŸ6mšo=ȵk×ä)ššš|OŸ>½Ð+âÑC*ë¥ByùúùÇ7®Þi¬é,)¿–ëhÍ,h¶å4&e^:—Z{êBUôy×Ѹ²C§J÷ÇEúÉÛjß°/kM`úÊ©K·'/„âg­Á)dˆ(ð.w¤ü¸'󗃹[¢ŠO”8]v(®<<Þ™Ps¡æTJÝ™´úøŒ†¤ìË)¹Íi-YÅWrK®”µ;\eÕ]®ºîhuW%‘Xz­ Z³r›Óí—S2.¤]:o«‹»Xs:±êx|eÔÙŠ£±e‡O–†D„æl ÌøƒÙý×ãÜáÆp8È«;ÝÚ{޾8b$‰Ab$½Êöôô¼}ûÖ •}ýú5Øà›7üÁܾ}ÜìÅ‹ýäyüøñ•+W^¾|i¥À{÷î¡ò}QÙeË–Yo!÷§EÝÌéOž|H*;Œž!ãaBøþÓÛ—oTå7¥œ«8r0gcŸÃ½é+Ø7-Ü Û ; ›j¿ls\ͫ쬨¿Q7ê óÓŸRïŠ:Qr´pWˆ}ª½-ùŸ£×pÙ‚ØåÕh„Ñï 1H RˆAb¤ ó‡ññãÇ?ùä“÷{å³Ï>‹ŒŒDŠG*ÛÜÜŒœø_äã?®­­µN®°Ñ„ ôrŒ‹º‘7„eš4i’æÍÊÊ2æ š2eÊš5kîܹ3þ|)5Ÿ9sfyy¹ä9zô( GºœÂÿÂêàÁƒøéÒ¥Ækjj¾üòK<,2úé§¡¡¡×¯_ÿ¼W”¶¡YpSsà+äG:šKÃÂÂp¸xñâ®®.\‚'OžlÈøæ›o´ÂÈà1˜Ãáøú믥>ð…Þ²eK]]Ý;©,ž·F©®ZµJòß¼ySIõ/¿ü‚ H”b·nÝêÆT¿úê+d@Ó¡SæÎ‹"'*‡³N§S»~âĉëÖ­æo½ïО¸PKÀ½Œ?žœœùÊÈÏÏ'•bIHHÀ}ÿð‡?Œ­Áæp7ªhËO­=}¬xw@Ú2³mÛ—½îXñž„ªèÌÆ …­Ù奰‘>­΢+9ØÆydÑî½YkÌOöÓ±¢¬D*»–Ûv·ùù+~T…B ƒC'b$Ie1kNòžIÀ%ÌTV˜9srr²•¼Ó§OGf³€¹IžGÍš5ËcžÕ«WK]ï ʤ¼HÕëCžµk×jbÿaŸÎ;g¾ò±îînÉ&üsãÆz¡1}÷îÝrÚ)å+iT*‹VòØzXЋùO-011±¯îèŸÊ"8³äY¸p¡ü£TW¡æb?úè£7nh ’Gjî& ÁæD4&®²ÞwÚ_æ®ß¶m›ÇkÁ«Ie‡R6mÚ„ûâïGÑÐ]i«=š³Á“éZ~$;\•RëÏÁÎÕu×Âæy­½^]Øjǘ:ÜÀŽämG#˜[æPîfx—a¬ÎfhF 1H ƒ¾+Ä 1H ’Ê‚8)ãJOOoii9{ö¬'3•7ÑÎÎÎððpI{öìYÿ7RÂŒKÌÅÁalAíäÖúzQâÔÖÖ†ÙE¸¡‚J"fíŒTVswõõõ¨ø’2CäÁ„-ÁH%ÿƒ³™©,õ>ŒéYD‡.7*+‚ Ò;vœ?é(Gg#q ¸þbìZõй\åä111˜Ç6H œH±Ne¥ã@æÑAhCÌŠ£5äÈ‘#¸ZÖéY7*+—Ÿ>}ºµµó±8TñóóÃHâB+ÕÇL¬õ¾ƒ›4ø¼¤ |TC\m6›$b^½¢¢ƒüZgÌë’Êñb}ßÝ”¯óÞ¸K!þ¡Ñ,mK^°?û×hÇÞĪ{“ ôbÒ¨hŠœ&–!Å8‚Ø×ïHùݺ£G\°°zŠ”$‰Ab$)>Ge1% º%ü «75|©/*»a÷텬̞uttH6x«ªWªÎÅ cT÷ý÷ß»­ƒEõ„ºQYðFóÊXͦ)Zg3•…§±UVVf\ÈŠ$•…Dzq±è‚ „ â1Ks¿øâ igY:«„¤Z³ï:Z§²h.ã\+H£¤ƒ1ó8p@Ò/]º¤TÖ¼"‰š?jIÙÆ¡õ¾3¯•ÅŒ´<»c¹m+Q»He‡LàR¥C ¾"ˆ¯XÙ^x¾"Œ±(ι"ó[2iª­k^sÆÙŠˆÐœÍn‘3°²á@¸¬ˆ$‰Ab$)¾Be䈈·S2ah¦²˜M5f[=S_SP‘§¿™v;uê”\ž™™i¼î¯s{lJó(³RQ‰Û©¬ÒoÌ÷J­SY!Z¨€Û±\vTìÝ8d ‰˜šîkç[Y3,i®Ott´u* îjLŸ={¶,[5ßÒ¹V#•…¸1–7»-»…€ÁJ¢lqd½ïÌTÖårI œÜ®]±b…^K*;dqç`¿eW_/—曵ØkÁ ÆÑõ!«º\´ÇƒÑª®ŠŒ†D¥D“zô¼¢YíDï?ÿçÿœ$ŽˆAb$‰ÁQ¤²êØ ]3—3SYñv „éV{,¢q¡Œ³¯:'iD!r#¢æ¹_!¥£`¡šA+iÊ wãr*EEE¦²æ§ÀS«íºß‹ÌÖBÀ±œXÝ€ÝîR]]mÊÂK\•®K &7Q—l#•E$-· [æ_ë2ië}ç‘ʪ3îëV=4—œ‚Ç2©ìx‘Û»³.ÅïÉøYŠŸm1""ô?¢üÓô‡¢aѼ…»üm‹µÙƒ2V¢#n?¾ÎߤuüƒTb$‰AbpÄ D8_¹ðîÝ»š¨ÁÌTVx©yþV¼C%²™ÊjL9¾sñ‚yò‚¹\) Sé(î8H*«| ˃5ƒÆ4¶HeñPf* Yc̸"±ÁºV½)¢ë¹ÝÕ°NeÕ»X¢F÷_õàU*»~ýz3•ÅcöCe­÷™Êbá5„ûÀا²”ú®2ì§&ÛÄU„c:šØ‘õ¼JÇæ~!†Ð)õ×ËùûôüƒÄ …¤ƒ¤²2cfö†³2SYÐ9üoÞ§°‹0œã¿ñ(ƼŸÜ¨ŸM1?é>ñkšDÜ #$•Ex!)6>>Þ­(04+TV7'ëŸÊª-HcLÒÜ+ê!lv•UßfIJêëÖB2•Êê3Z§²ÖûÎLe÷ïß/)è¾¾j·ö1Ke)wŸÜÌiLÜû›{vŠ‹qìÃRZÓÑU,¾:^²¡D¤_‚³Vç^¾ÀEDÞ€_b¤ƒTbTRPPÐWXÙ|żVVw"Õ­D‘Çm¨Y1H§æÜÂAÍîÄÅUÎóüùs·Ë%6sŒCHe!æ€F"Û·o7SYÝWFáv­PYõþî»ï4Q»z! I›©õÀ¨,D"{¡þ µn— ”4nE³ƒ¤²ÖûÎLeÕË”ÕíZ8  zp®fا±) Ý®Xg¨Žz"úbRõ ¬]¡ùôÅZ,t ºF»)®ìW:~‰Ab$©Ä ©,ù¸¹˜j_PTñ‡Œ9ªÇ·/S”£‰J,!˜ÞTJƒ¹\cP TF}•‡–Ê Íó'72(ÝU©¬lŠ‹…Án; Y¡²Ê„ñ r#•½{÷WcîT´Ö¼ y`TkPÍQ‘!Ø Hý«Ie­÷™Ê¢(ùìöDX€-I*;ÖÄy5gö:µ ÑŽ=¹Mi´—Þ¬9M©Ø[_»,ľÁÑšIN R‰Á‘bJ ’Êš¢þB°5‹¤`z¤¢Ÿ}eøMøæôA¶ZÑ?‚³Â*AlœN§$: †$¼ r’§´´T·«ÁL¦dUr*«1‡°š÷áǸæÁ»ÌûÊÊ4µaÆì´D¶HeÕ—DwÑ I<¬Í‚€Uêà‚†í @Ê€©¬²G¸‚c~X…¸¢x–ARYë}‡N’â¶Ü‚­†u¶×®]’¸gÏRÙ!“½‚FK:îµènxÁYkªb\e4>´AßùÊè½™«¥£ŠÚîb?. 1H%GAˆA*1HnŒõ¢à~J\Áâ„\yœ•UÁY™fÉËË{ç0 §ùÁôÀ|´(Ù›‚r4è1(.Κç‡Ê‚cËÔŸˆÞÎLeჭ‰ÚbÖ©,xÞœz9fYÁõ¦Z<µ¦ãigü0••Zi™èbDÌ’CÝgTÖzßAôYþÃÔJ3£hmaL†cj—Tv,Œd¿îy•^'¯þÀŒŸÓêãi}W±î^€½"Þô¥bJ Ž´ƒTbÀ„k+¨‘˜}ýõטz5ÒB™"ûüó󃃕uH¬µx#l:ªüM‰ Ü\ÝVŸªs¯ÊÎ;³¾+W®4SY­¤™Êbéi?×b3„ʯðÏÂ… Õ#Sµšј¢‚z‚ óßÓ-…ú €„WkÖ¬q{4Ü íï–MwèQv®+ÿ+í7Knn®äÁð„ù,öIÒŽÓb/^¼¨Ô½ɺ»@›¨,b8©c¹õ¾s‹óÁ̼†hƤ±Ûp dÆØç©,©lMGIðoC˜±e‡k»kh}]ënÔÆ–‘>Ý—µ¶®ËIKL R‰Á‘bJ ˜˜3DŒ\,tÄ$›yNOE¹ø'vë­KsÿÉÎÎÆþº3`ûÜÆÆÆ"Ø‘™¬×½s玛£¯¹n ä¨?Ö—³ZÜÏŽÑØqs›}ewEgmäÁ ZÞ¿puFÛÂÍ{°Å¢ïàçŒlíííZeÈð1Žˆˆ@ ß»wO}›Ê’ÊÞzÔuæ·˜‡ó¶´fÑø%-hÉ:”»Uú÷\EØ=†v$©Äàˆ1H% LʶmÛ?yÕªUæÍru£T/ ©¬÷ß7¯)Y^îþ©K.Öœ¦Á«šT}rGÊèè) ­| ƒTbp¸…¤ƒ&þÀê(«óŠp¢–D¸Â°\ ©,©lZ]¬ØolËÆ˜c^ËÛÇŠƒ¤Çó›°†žB R‰ÁabJ ˜x´bm­£’xHÓX5SÆHeszen”X)oó´KçÇ›1«îr•\+À¶ ©õñƒO¬:_u¶â(G, ‰)ÙUQ¸+,\’Br6îË^‡Xˆé+w¥þäg[ŒÝØ¡~¶E8D"¢J Cˆ}ã¡Ü-Gòw-ÜUí>QzàtÙ¡¸òðs®HÀ¼Ps2ýR¶Ôw¶Õ\¯­gO­?'ýî¼jç[†$‰Ab$‡U¸‹65ˆ±ÆsÂÖ;ä±RY"ö´3/q!û唱须¦¬Ýå1`x¡úä™ò°hÇ^¬€Ú›µÆß¶Ï>êº3u)öx8’·CõPIT5¿%³¬­¸¶»zXR‡šÎšðáb$‰Ab$•¥ êoYY‚Kä§ …T–ˆÍn8×7†Q Z³Ç€µÆÈ.Bt$מ9å /ðßo_¶¬ó‰Õ2B>˜»ÃÆ:fï’1ãS)ug°CFCRöå”Üæ4|_ÉÅè5¾ à~†‘l|@«»*qˆÄÒk…È€:ä6§ã“(³áømuqæqîˆÂ€ÐœMØàa{òÂþkˆqnŒpc8bü¸èJNÝÆÒĹܨéf M81H ƒÄ 1H z»ÊR(¤²Dlmg©¼»íM6µÙ릉® ñ®¨È¢ÝººYw§¯8`ß7'ØNØQØTûe›ãj^eg…7<Ì? ?L~J]žåDiÈÑÂ]!ö ¨ö¶ä?z|"Œ^ã›Ï’Õx0È àÃeú¥,ê¸×BN ƒÄ 1H ƒÞ+¤² ©,ûèù}Ûb¼¸1ìê3ëy®Wb<8¹6–ãÇÝ¢0p{¬xOBUtfã…ÂÖìòŽR_b¯èpbÛ#Ç— üÁÌO¦8˜»£éöÆÒ£ª®?ùÓ$ÆŒröd¬Âƒ&œ$‰Ab$½THe)RY"ÖÞ˜ˆW6L‚÷‡£ÈlH‚Íö8ضüHþvƒÇQ-.óZ{½º°ÕŽ1uŒ"ceÁãpõ)çAŒU[§!p\ˆM81H ƒÄ 1H ƒ¤² ©ìÀeF¯ GÉoz^Ëâ,eñÚMÌáb$û˜«"Fâþì_"±*Î`¦•ÌT4EN“ Ë0¨|À¾~{ÊïÖÊÛ ¬wnô2ïN[Þó¶‡ï&b$‰Ab¤ÊR(¤²^wß’Ö,¼¬½Ð«ìÂE`‘ –¾ ÀƒÑÁ‡ !ÉÐzQT¸W­ˆÍÙì9Í›R{¦¯eEØ;A÷$ ƒÄ 1H ƒÄ …T–B!•õ®ûÊzˆpè Æ&ûr2„°¶ÇhlMQ2±ªË5˜Â©X/„- °|MêÑóʘŸP8•àŠà»‰$‰Ab$ÇžÊÚíö€€€˜˜˜~òØl¶õëׇ‡‡b=‹ŠŠPϨ¨(‹ùccc>œ••õâÅ ë7êèèèCÐJOž<1ßËcþÐÐP4owwwÿw¬©©‘ü ï¬^yyùîÝ»çÌ™ƒ x?øàøé,\¸0==}\SYRÙˆB¼©óFÕ«ªäZþ™ò#ÆM°Ó:–© ô?¢üÇ©hX4/vº—H'¢»Ò~Š-?‚î1l¤DøÓNCˆA*1H ƒÄàRÙåË—£òS¦LÑ”ÌÌÌ .´´´¸å™6mÚ(ÖsË–-¨Ã¤I“Þ™óõë× ,@f\ÕÜÜlñF999ï½KæÍ›g¤Çqqqýç_»v-jÕ×ÁK%Ûûï¿ÿòå˾²õôôlß¾½¯[|þùç]]]ã”Ê’ÊŠá­56é—ÂòýÔ„`{€¸Šð^­DÅ6÷ ÉÙ¨NÏþÁσvš¤ƒÄ 1H Ž!•Å\R0õç£TvçÎÒ#3gΜ5k–üÿÑGý©TÓžÓ~/ šJ1úêÕ+7*‹<Ÿý&nù/^ìñvwïÞÕ<‹/zÌöôéÓO?ýT³ý¢ƒ"""0[.ýùðß?>©,©¬¼²±¡ÜHڌҶ"˜jì'wÇNq1Ž}þ]KFÅâ«ã%ûJDûï?½MSM R‰Ab$ǘÊÞºu þ±mmmc†Ê‚‚©#ü¢¥ƒð¤©l?¬³»¨ƒd())q£²µµµnù].—´'h­Ç‰Ù#GŽà¬ÊW_}å±V~~~ÊWÝf˜Ÿ={†)Y9»råJRYïElN¯ Ÿ O¿t~dŒv/Ø©£žˆ¾˜T}Bö|£z‰b-:]£ÝWvèòê1iq‰Ab$‰A*1ȰOÖ©ì7à òÃöþýûÖó €Ê¾yóFºCWö:NI¹råÊà©,¤°°P2½“ÊBBBBälAAùìÔ©Sqêã?‰•l÷îÝsËsóæM9…®Áô¬¹ŒDà¬fRÙñ…X5ánÀ)A?«UˆvìÉmJ£½ôfÍiJÅÞúÚe!ö ŽÖLšpbJ ƒÄ 1è=B* ?Õ)½rôèQM¼}û¶$ê¥RS$®Zµ ÿ´’g³²“'OFÎO>ùDW¬X!e‚å •U—`4‹*‹èSr! Ì-#§ÐΈù$ÿÃmØ-Û¦M›Üø¹YÐw’§ººzœRYRYÄ–VwD´× U1®Î2²dÜ ï|e´nÇUÐv·™&œ¥ƒÄ •$•µèX‹•š’””¤äP'ëÀèd gpp°ÛZÙüQ2« ¬®æÈ…*’~ÛO­êëë‘Í,¨í;w¬ç±NewìØ!—‡ôŠüË5à ©,¸¢dƒ}'•Å<³N·brÕíìš5käH;¦[åÿéÓ§»eÓU²²:׳0‚1©,t86©«¹^…M¤üÀŒŸÓêãi}W±î^Q÷¦ç5M81H%‰Abu!•ÕéGe­X9©´»ÈH"þ‘”K—.¹QYY7+|¥á8»jÄjjjºzõª2Fà~j&³¬p¯EP¢Ç?~\. ³žÇ:•ßÂR­°ÌÐbAéPYlÕƒ¹hÉ ƒ•Êž>}Úõ› ie¡f.n_î¹sçJ #{ô…¥×>êOHeIe£Šƒ†öŸZ.0}¥[v¸¶»†VÐ×µîFmlÙéÓ}Yk뺜üŒ&©Ä 1H ƒ¤²£+ØDǵª·°ÎÁB°Â‡pþS#C@_Íë<Áû©•cL?á<, D­ç±Neá¬l2þ|Ód¦%*‹èÇK ‚r„RªK°õÍx¾ùæ»õÊYÝVSäI³a{Ýn§¿z“Ê’ÊŠ­µ_¶ É‹Þq5ÿèo1-çm+hÍ¢ñKZÐ’u(w«ô﹊°{Ooó3š¤ƒÄ 1H ’ÊŽ–`âQj²ÿ~ã’N™ëÃö0’ S”8\¶lÙ¨¬[Ì!Ù¾ùû"%y°RT#E[bê¥YÌcÊ:)MöèÑ#œÂTç‰'°$uðûÊ¢ eêÛLeßÿMÌû¾º-ÇcÔE)k• ñ˜æn]¸p¡oƒ‹TvF¯ Ÿ G¤>ü /ð¯ë®äûýœ+RÊôO]r±æ4 ÞXÕ¤ê“;R~DGïHYèhÍaDƒÄ •T!©Ä ǧ9I§ï’““eÊ455U_¼x!ÿ#ñO¥²H7G~'•…C²1˜æ6á… Ofëy¬SÙ––-.ÊÛ·o—ÿÑ,X!Œ)e ^e}Vv±AP+Ù*VÏ"sÿkeñEEE˜"6o-‹5Àºíƒ¨k4/kfL¡ë`DŸB*Ë}eñFŽ,Ú ü³%À)g¨ˆmÙÓbÌky»ãXqôx~S2­51H%‰Ab$•ÁÊR™ÄÜæêÕ«ñ?þbNRjX^^ŽÅ¨nó«Ö©ìG}4*‹š€Ršg)¿üòËëׯ[ÉcÊ"¿\XVV†Ã·oßjÈ%´Æñ¢f­lww·î+‹ý]û§²º&žØn˘:ô^¿‚6w[oÜÿ³c¯8Bc^züRYRYµâˆ²XÞ^2€º¬O“ÝùÆ“Vw¹J®`[…ÔúxŒÁ'V¯Œ:[q‹£N–†Ä”ììˆÂ]aù;à’’³q_ö:ÄB„?Û®ÔŸül‹±;Ô϶‡HDT d±oD_Éßq´pgTQ`´#øD鄉+Ç?`^¨9™~)[ê;ÛŠYd´ž‹Á¤ßWí´ÖÄ 1H ƒÄ 18òB* Z© öÈ‘ù=,¿D:‚ââÿ½{÷nݺÕm~Ï:•Åüᨬ‚9a)ïÚµk¥V"ølÓJ‹TdØm¾Œ]JSÉÎÎdãhQV¨,dÆ nñœ´V“M¢ŽÊºÄÛ&Ibkkk_ÕÖ)èñNeIeÕŠ°o€A¡u…S.„²_N›‘ºkÊÚXƒ†ªOž)‹vìÅ ¨½YkümKð죮;S—b‡#yÛQ1T•DU³¬­¸¶»z˜7K<)u¨é,¡µ&‰Ab$‰ARÙ‘™3TbóàÁ$nÛ¶M,è(þ9|øðÈPYL#–oUU•1ÌI¹™•­›ý‚“ÊŽw*«Vc¢)ugphEa0ä’‚Öì1`­1²‹ɵgà'†O“ýöõiËú7ŸX-ƒ!䃹[0l¬cÆñ.3>…–Ä  IÙ—Sr›ÓðP|%Iø&€ûF²ñ}­îªÄ!K¯"êÛœŽO¢Ì† à·Õřǹ# Bs6aƒ‡íÉ û¯!ƹ1Âáp\ˆñã¢+9uCKS׆5ݬ¡µ&‰Ab$‰ÁRYñ+Q—àÂÂBM”¹Á‘¡²ÊúÜöžÅ R]j%*‹É[¡¬˜Ãt;µyóf}vl/4H* ?mÉk…Êâ¹ä,ئö‘¹#T°×‘œýú믕©Ê$>>Þüà˜Ê–³Ø~‰keIeg’¡0H%×ò‘ÒÂ8If{“ÍGm¶³­8«ñB¼+ Ÿ/ººYw§¯À8=Üœ`;aGaSëÒq5¯²³Âžæ†&?¥.Ïr¢4;þ‡Ø7 ÚÛ’ÿèñ‰0z.Ƴd5^D# ²²w¢_Ê¢Ž{-´ÖÄ 1H ƒÄ 18’B*«L ¿V· ]ÌlÐLee~ï‹/¾<•Õ™Òo¿ýV§CAÌÀ¸tÉ®•<ŒQg¹$44T(+¢+©?°‚0aÁê`¨¬RSlëFe=šg¤«k1$**J"3 å†×·¹p7÷c4ŽÛMeÝ/&±_ô V£Ý${=yò„TÖ{›Ó+#f¡™ IbÌ0Š ·I4kEG©„ïð«Ï¬ç¹^‰ñàäÚXXbŒ{t‹ÂÀ-–<%TEg6^(lÍ.ï(õñ!vô”#ÐØÆ9¾Tàf~j4ÅÁÜÍMǰ7– ðIŒ#åìÉXõèù}Ÿ±¸Ä 1H ƒÄ 1H ú>•ÕÅ,=u $D¨*‹P½Z¢ r­,v‹Õ9IaB0au÷ݸq£Å<©¬Îg*µÓÿQ¬lJYºté`¨,"QI8l[ÜWVvHÂô©F–ÞÛW•ýºÅô2‹®¹­««×Œ¹¯lqùJ°ÚD2À¿FÝœ'®"ga¼?ê›íq°9 mù‘üíêq$;1Œy­½^]Øjǘ:F‘±²àq¸ú”ó Æª­‡ÓÀ8.´7&rð˜$‰Ab$IeGRte&öeÕÄàà`I„C¯1³L~bPSJJJ”h3•ÅÜwRYÌ©Êå*:cŒùIëy°J[ÿÏï_0¬ëcýüü$E!ˆ±›o°Y0›ê¶TÕ‘X2hŒ¥³gÏjŠÛ­qG0g‰¨,2wîÜwº:cy°n`kL¿té’ní#¢Ã2¡M*K*ëY±ÄewúrÝçÝ•Av¦.A:–²xí&æp1Ò}ÌE#qö¯ø:I¬Š3†i%3M‘ÓdÃ2$ *°¯ßžò»uG‡ò¶Âëýãǀ̻Ӗ÷¼íág41H ƒÄ 1H ’Êú€­aŠ›Í U ¡öööôôtÌ+†‡‡c®[ÚXÏ3€Ê£æÝŒÉR,¸ÿä±$Ø®‹Ÿ1a›˜˜ˆ‰èþü¥IeIeU]N¼»ƒ2VIæÐœÍÂDzbõ ±ë^e‡.‹d°ô.aF *„d@$CëEQá^u¶"=î9Í›R{¦¯eEØ;ÁúžüŒ&©Ä 1H ƒ¤²ʰ©,©¬(VŒ`œ2ø·µ%­Ä˜.þA„Co06Ù—“á „µ=FcƒhŠˆú€‰U]®ÁNEïcK,B“zô¼2fÆ'N%¸"øM ƒÄ 1H ƒ£,¤² ©,©¬.,«•oѼQõªB`É3åGŒ›`§u,SA%eK@ê+Í‹îým‹µÙw¥ý[~Ý!cØH‰(ðçg4„¿J ƒÄ 1H*K¡Ê’ÊÎèo0᪛”=ÜFkMú¥„°|?©¿lgØ#¼Z‰Š8lî’³Q;Ÿ+üƒïªáE1H R‰Ab$9>E¡Êr_Ù¨\‹ åFÒf”¶ÁTc8¹;vŠ‹qìÃð'­éè*_/Ù‡P"Ú/ø{ÿémZkbJ ƒÄ 1H*K¡x£ÊÒ„§K,ÇáWì"^°SG=áÜ•T}Bö|ó¥b-:ÅèwWvèòjZkbJ ƒÄ 1H*K¡x—ÊÒ„clx¸ V¤eü¬V!Ú±'·)öÒ›5§){ëk—…Ø78Z3i­‰A*1H ƒÄ ©,…â-B*KŽØÃꮃˆö$0¡*ÆÕYæC–Œô¯ŒÖíø£ŠÚî6ÓZƒTb$‰ÁÑRY …T–&:›ÔÕ\¯Â¦R~`ÆÏiõñ´ˆ¾«Ž¢»dÔǽéyMkM R‰Ab$Ie)”±RÙœ^ñZU„Ã!ÔÔúsé+¥ðزõÝ5´‚¾®u7jcËŽHŸîËZ[×åô~‹K ƒÄ 1H R‰ARY …TÖKeð&\l­ý² )ƒWÇÕü£¿Å´8œ·­ 5‹Æo,iAKÖ¡Ü­Ò¿ç*Âî=½ÍÁcbJ Ž‚ƒTbT–B!•%•E¤>ü /ð¯ë®Eâ`ôœ+RÊôO]r±æ4 ÞXÕ¤ê“;R~DGïHYèhÍàg41H%GZˆA*1H*K¡Ê’ÊâŸÈ¢Ýø'¬Ào0[œr†JØ–1-Ƽ–·;ŽIç7%ó3š¤ƒ#-Ä •$•¥PHeIeÕŠ#Êby{ÉŠÒ€õi²;ßøP*ƒI¿;¯ÚùM R‰A+B R‰ARYÊÛ·o;;;oܸa%óýû÷Ÿ>}Úçi ©,©¬Zñö %× þ¤rà”… ýl‹ì—ShÕÆ›^¨9)?¤šÎ~FƒTb°!©Ä ©,¥±±ñ“O>yÿý÷¥ñ?øàƒ¥K—>|øÐ˜çû￟2eJtttIIÉäÉ“‘mÙ²ez–B*;Ò2£W¼Ü„«GŒ”º3 9S&—´fÓžOÕµaM7k†LÄ 1H%‰A*1H*ë“’ðžI„Ð655i¶éÓ§#qîܹšÁ3•¥Êr?=O&Yö,¹–ß Ø%O2Û›l´dãYeïD¿”E÷Z¸§%1H%Ý„¤ƒ¤²”Û·oc2Vˆk^^Þ³gÏàc*½€Á>x©¬ÈìÙ³ƒƒƒÇ»o@!•¥ ‡f6$íÍ\S»R‚ÛL_—Wt”Jø¾„ªÚ0jŒ#?†=«=¿ÏÏhbJ …¤ƒ¤²”•+WJƒ·´´ÓCBB$=99ÙÊY-B*K®Š Ñ޽’K€`ÔÍyâ*Âq¾XrH¥-Ü…Ÿ„½1‘ŸÑÄ •4 1H%Ie)&L@kÏ™3Ç-ÁŸ¤#¶mÛf¤²“&MzóæÕÒ)¤²4á¦H§v§/×}ÞQk»«w¦.Aznsº¤P©ø1à'±;myÏÛ~FƒTb¤ƒ¤²‘/^HkGFFšÏÂå§¾ùæ#•7oÞÀïG!•¥ ‡º:œñ•QA«$shÎf[]Ò«Oˆ]7f¦R±…qO~FƒTb¤ƒ¤²”ææfiíôôtóÙiÓ¦áÔÌ™3T‘Ùn¤²^Øœ^ñE.Š-㫎g­‘KØ×ïÏþÿ$מ1f£RSêâðÃHpEŒü[†¤R‰AbJ ’Êz§tttHk#ˆ±Û©×¯_Ë)ìÁ3*K!•å¾²–´öz5\­Äx‹æÑ«ê÷JÍkÎÀ#¢ÀŸ{ZƒTb¤ƒ¤²‘žžií;wºª®®–Sþþþ¤²Ã%¤²¤²ª ‰Û“âÚŠ'ÕÍ?Œ€´eüŒ&©Ä  1H%Ie)S§NEkOœ8Ñ-˜Ó¡C‡¤# He‡]HeiÂõZÇÕ¿áþuݵ´aãYñÀÏ@~üŒ&©Ä 1H%Ie)¯RYšpüY´ÿ„øUuUÐ’OEׇåûág€ùM R‰AbJ ’ÊŽ¡Ê’Êæôʘ4ájÅån)o/¡=oŠN?˜»Eí7tÔ7! ©Ä 1H R‰ARY …T–ûÊZºV¬øû†’k´jãGK®å°¯Wûí3&œ¤ƒÄ 1H%Ie)RYšpµâí ¥î mÛxPt4º[í·/™pbJ ƒÄ •$•¥PHeiÂUÏ”‡IzTQ Æ)iäÆð 4ºXúŽ~FƒTb$‰ARY Å'…T–&\4³!ioæjœÚ•úÓ…š“´vcOÑ­è\t1:Ý4áÄ •$‰A*1H*K¡ÊÒ„›âD;öJ¦—·2&œ$©Ä 1H%}t|ŠRTTeý’<|øðÙž={vãÆ üµRæ›7oº»»oݺÅ!•å~z–®uu8ã+£‚2VIæÐœÍ¶º8šCßRt:Nz]‰E·ZùmpOKbJ ƒÄ 1H*KÙ²e yÒ¤IïÌyïÞ½µk×¾ÿþûÒ/øçóÏ?okksËöúõë°°°‰'J6È´iÓl6›•jôßÝ{÷îE†ü‘T–T–&¼N÷ O¬:œµF.AÌúó•ǸW—+:Ý$ @Ñ}èDÝýŸŸÑÄ u•$©Ä ©,©ìÝ»w‘ç=“€Ð^ºtI³õôôÌ™3éf9qâD_…j¶¾ò¼|ùròäÉÈðÃ?Ê’ÊÒ„ÿNk¯WÃgö¯r!ôhá.[ÝÙê.í¥÷(º‚®ÑnB—¡ãÐ}’ŸÑÄ •$‰AbTvÈ…TvöìÙÒ«W¯nhhèêêÚ³g¤|öÙgš-88X?ýôS‡Ãqûöí .ÈD.þ>~üØãdï„ ú¡²ð=®¨¨À 0Î’Ê’ÊÒ„÷§ ‰‘EÛ’ÿøÛ‚“'KCršRi>GWÑèt‡ô :Ý„ÎÒ üŒ&©Ä 1H ƒ¤²cO°ÖôþýûýdÀD(ˆ¥Å<£².—KúbݺuÆô%K–HúÓ§Oqˆ¿|ðzàùóçšíܹs’Ín·› ÿꫯä¬ÇîV !•%•éû¤-Ãë²¢Ãé+&\ýv°ÚÄ88}À¾!¶ìpVã…ª‘ŸæØsevcrlù4¾qø]£žoüŒ&©Ä 1H ƒ¤²cFÞ¾};sæLPÁ’’xäbnSKOƒ‚‚ÀH™ëêêt²ùý÷ßK@&ëyÌTöêÕ«s{%99YRV®\)—»×âŽ÷cbV²åää³½xñ¤ÙJKKÝžá¦dÂvÅŠ»NŤ²¤²ïœ^Ž’# ýñºÌkN÷-®šÕxñXñž)?ª ñ³- Ëß+RÐ’E+;Zt%'©ú¼§ül‹µÙÑètÇàË÷¶MˆAb$‰A*1¨B*+Om¦pâÊ o[ÉY__oÎ ¤÷Î;Öó˜©lYY™dÛµk—¤|øá‡8Ö,éš ªŒ%zôÈårUUUéY‰Ï$dÒÚÚj%*«þÉøß<ݪsÈÈ ‘œð¿y{X-nÉL¢SÇrxêÔ)RYRYïºïigˆìG‡ð†ã΄[pÇÂ>r0¥ØíàlÅј’}XW³/kÝÎÔ¥x/QTUBÅP=TUE…Qí¡u‘âg41H ƒÄ 1H ’Êr_Y̦š'6…sæææJ6xóIºÓé´’Ç"•ýöÛoÅsøîÝ»Á‚3ã3Ér˜——gÌV]]-éès •%•õöûÊözдKçiÂ-jíõjg[†QaáÑ[vø”3ôxÉ~¸6aC¿ˆÂ]ð_ÂNs7°o@PĽ™«±1"LÀèîHY„¡b(þÁ!q  ™q .Äå(E¡@‹Âq Ü·ÃMqkTÕ‡åg41H ƒÄ 1H ’Ê’ÊʦÄF|à+VH"(Rîß¿/‡ ™Êx±BUWœâB+yÌTVBOé•èèhIiii‘KfÍš…™XI_¹•DIA=QŽÌ¬ ¹…´··£(a¨©,©¬o¿)ÒêbåŠ8‡æý4áT~FƒTb$©¤²¤²º¨Uo?ûì3]‹ÝbÕ#.»³gÏÖlˆ l=™Ê"B²äÙµk—9²ÌOœ8Q·Ø1ÎúÚl6͆2‘S<HeIe}þM‘×”,¯QÿÔ%X‘BN¥ '©Ä  1H RIeIe±o ökÅ?*à¢Æ}t0§*ó«n²aÃ,¦µžgëÖ­ÂNµd6î£.ê 5D|cÍ —Ëܬq q9îGàœl‘Ê.X°€T–Töw’Ó+#yÇ[ºÎ8Cåe Çž‚–,špêØß„€¤R‰AbJ ZRYðF‰«tþüùÄÄDZ¬¢î»Øo6,,,<<aŠ»»»-å¨ÀQL5&&&55Å걊º1cª6...>>ÿÀñ‰RÙ±&5%Á™«å•ŠE)µÝÕ4áTšpbJ ƒÄ •„ÊR(¤²^-¯{^¥×ÇÉ[aŸ&œJN R‰Ab¤ƒ¤² ©¬Hǽ–èâ@y·g­M¨ŠA$ šðq«4áÄ •$‰A*1H*K¡ÊúŒ8¯æìÏ^§»·Ñ„C¥ '©Ä 1H R‰ARÙØØXò7 ©¬ïIC·+ÖJN¥ '©Ä 1H RIeIc(RÙþdF¯xU‡Ý{r‹&ÜÇ”›ƒÄ •$©Ä ©,…B*Ë7E@Ú2¼j+:œ4áTîiI R‰Ab¤’ÊR(¾!¤²|SDúãU›×œNNåg41H%‰AbJ*K¡ø†ÊòM‘X‰Wmríšp*?£‰A*1H ƒTRY Å7„T–oŠ’Ö,¼jçm£ §ò3š¤ƒÄ 1H%•¥P|CHeù¦xÓóZ– åºùVÑ„SùM R‰Ab¤’ÊR(¤²¤²9½â…ÝfoLÄÛ6²h÷¸5á öó –ÿqņrx ‡wmôÚ s‚ñŽAbJ ƒÄ 1H*K¡ÊR=¿ïo[ŒnBUÌø4á»Bwâ'ñ/ÿõ¿”Ãå¿.Ãáäÿe²÷Ö™&œ$©Ä 1H ƒ5…B*K©í,•w®ý²&œ&œŸÑÄ 1H ƒÄ 1H*KVyûömggç7¬d¾ÿþÓ§O=Ÿ£ÊR²Î㘾² 5›&œ&œŸÑÄ 1H BˆAbJ*;äBillüä“OÞÿ}iü>ø`éÒ¥>4æùþûï§L™]RR2yòdd[¶lYŸ%RHe)§!xíúÙÙ/§Œ¼ /ku¦;Ó«:*YNíõšœ*{ÉeÇ;³Õu×Z1á5ÕÙ®¬Ú®šT“U‘éj«xgÎÒæ+V\-w\.XË”_)ó¼3òÔ qø=´B ƒÄ 1H ƒ¤²”„„„÷L"„¶©©I³MŸ>‰sçÎÕ ¤²¤²D¬¥íõ i—ÎŒ ‡i\¹qåÿôgÿ“õßý¯ÿ.âìQÍðÿð¿Oš<é/ÿú?™¯ùŸgâÔßüýßÈaR^âÇõ±–“üwßüÙ4î Ù9ýãéÿä¿ú'Ðÿ÷ŒíÁÛâÑ„§:lÈ©þ‡ÿã?$æ&X|®Ã§¡½ˆÇÄwƒ[¶c磤2Rÿòåg1IÑÆ [7ãç|7ß%¨-²ýÙ¤?³Þ&ÐŒ²ôÏþî?ÿÛÿæßâZyäû¶/‰ËˆÃ%¨me»ë»ÿ?©pA]>?£‡PˆAb$‰AbT–rûömLÆ qÍËË{öì|ŒCCC¥f̘¯c#•™={vpp°ÃáÐr(¤²#-3zÅû{1­.VÞ¿ÇKö¹:ˆՄ;[J§ý_ÓÞó$óÏ—<_Ïû{II+I5^ û*é«6ýŒÃ ùIË™ð?N(j(”K0ÂúÃOß›óÀvšM¸R¥X/7áÄ 1H ƒÄ 1H ’Êú¨¬\¹R¼¥¥Å˜"éÉÉÉnT6((‡«B*Ë7E^S²¼‚ýS—\¬9=|&üÇŸ”f™¿è;8 a4ô´íÌ•$b¤yN^žG&¸iÉ3ºrÉcûÕ †Ç†Áþí=ºGì·Ù„‹üÃÿ!¹(Ù^iß´ER0¬[q­?G)˜Fɉ1clo€ávø)á%ñbÁ®Ölg3ãÏ‹‘xIÔñx1á"0þiíOû"÷Yl“¼š\ýŽ9rú0ng TK"ßÍ„K#|¿ô{<,ú‚{Z¡ƒÄ 1H ƒÄ ©,e„ hí9s渥#ø“tĶmÛŒTvÒ¤IoÞ¼‘ ©,©¬U¹õ¨ëŒ3T^ćó¶´d ¹ ‡™‘6û“1k``rÄbɲ¼³Á #–[eÌõ—ü£1J‡()Š=ÃjÍc+NéË„/X±ÀXü‘Ì£ÅfMÈIl0ÒÆ%Iò°ÁbæÅ—ìÏÿâÏaãÏ.PŸþí§n&|Ög³d•õ6ùûo¿’1u±èZ8_ÉóÊ’!5á(3¿6oÈÃ]ÐZƒÄ 1H ƒÄ ©,åÅ‹ÒÚ‘‘‘æ³p9Æ©o¾ùÆHeçÍ›Çv#•%• Ôt”g®–×qlÙáÚîê!4Ỹ Ъ~óÿ¯œ£µtÍR9Ì,ÏÐå@’²/"XRÔ9  VJ†1,ø?¹ð¢\²mï6·ÛÉ­Ù„ãZ·Ø0‡2D-«›P²QeW½›¦þÇ©¸©^Ž1l(¡/Îež•<w«Ì· ¾5>»šp{e¶æ±Ò&0ór_2·[„DS'.7šð݇wGäFZkb$‰Ab$•¥477Kk§§§›ÏN›6 §fΜi¤²ˆlÌv#•%•¸¼îy•^'oäÀŒŸÓêã‡Ê„/ùe±Ñpz÷…SÓKÓäpÝŽµÆ1ZT Џ`ùÞA_Ìù[$¸á”›#V¹ÝnýÎõfŽ‘]sÅ$ú"Fh¼Gö†bŒY±¶1$`ªåKBtOxœE=ab ?+9O3yRs+YiìGn·Qj¾¢Ä„ëŠ#~FƒÄ 1H ƒÄ ©,e8¤££CZAŒÝß3¯_Ë)ìÁC*K*K*;ÔØ»×](ïåଵ U1ˆ„1H>û«Ùf× Ñ£qáÒ\X #)ñÑ_HÔ9·¢øa®Ñ_´æÐðGÊ­ÎA† ;7HJqc‘Ûí‚î5›pµÇæqkXh‰Ù— LjÁè1†‡ø2-[÷Ó{ïŒd«a†–±VÚ#Íï¼ÖM8¼ªøM ƒÄ 1H ƒ¤²”ážžií;wºª®®–Sþþþ¤²ÞˆRÙœ^ñév^ÍÙŸ½¯fÑAšpŒ‰ö5è‹(n^C:>Èê•„(nb æŒàxJpßû–Ìl±VÇ-›Õø«ÿòWø»ÿÁŠ·6fÆ·FQ–ýˆ`d§0„,‡¸ÂFQjÀ$97‚Çh·äñ8­‚³ÆE>¨ó;?M4r#¾QðUÝôr]G„}Ûµ†pˆBLH­âXàaû7áVÚf[ol¸n¤…•EÃdÂñ“À?~F›…$‰Ab$Ie)·oßF쀰°0›ÍÖÞÞŽÙÚ½=…T–’X‰7urí™Á¼îžABeÅúåG|ùÐmWãÍ:ö,¢Û»cW=ãVùë¿ùCÎFŽ!a±ˆk¶­Q++P[+•íÊ’À"z¹nX§VÜ-n÷óÆŸñ,nnZºøÇz›ˆb‹?ý¸QA´ƒÙ-Möl¼â'~üŒ&‰Ab$‰ARYŠÏ ©,©ìŒ^Ký]Òš…7õá¼mƒ|ãcH{Ü DìØH1`SØNøm ÜŒ`Œ÷…D¢yŒñý±0éà‰ƒ}çÐr\Fv)@ø ùª°®Ø«fu½ÿ¯¸‚m`1’ÇlˆN‰lذ.OŽËÅHr-j(Œ<6ٵ˓2¬ŠŸ~øyxË/•$‰Ab$‰ARY …T–o •7=¯e™Pîo¾UT*~ ²@?ZkbJ ƒTbT–B!•%•õF±7&â}Y´›¦K”Š~øaÐZƒTb¤ƒ¤² ©,©¬—Ê£ç÷ým‹ñÊN¨Š¡õ¢âg€~øaÐZƒTb¤ƒ¤² ©,©¬÷Jmg©lžf¿lÏÖ‹jo²É/? ZkbJ ƒTbT–B!•%•õvÉn8w`úÊ‚Öìñi½¨èzüð3ÀÖš¤ƒÄ •$•¥PÆHesze¬öýig^ß~¶EöË)ãÍzQÑéèzüð3ð2‹K R‰Ab¤ƒ¤² ©,ÅÂözдKçÇõ¢¢»ÑéƒØ@ø%©Ä 1H%IeGU(RYJZ]¬¼Í—ìsu–mÓEE££¥ÇÑõôƒ"©Ä …$Ie)C%Ïž=»qãþöŸííÛ·÷îÝ{úô©ÅboݺÕÝÝýæÍ¶0©¬»Pòš’åäbÍé±j½¨è\t±ô5:KzˆA*1H!‰ARÙ±$ííí.\HNF玨¼~ý:,,lâĉÒ5iÓ¦Ùl6sÎÆÆÆ¯¾úJ³M˜0aùòåýsÚììlÉìr¹úÊóâÅ‹÷ßy:;;Ç•%•¥ÜzÔuÆ*/÷ÃyÛ Z²Æ–õbd‹,t«ô/:ÝÍèÄ •¤ƒÄ ©ì“ˆˆˆ‘oœžžž9sæ¼çINœ8aÌYVVæ1ÛäÉ“Ÿ?î±ðÛ·oðÁ爐§OŸ–¶ìpmw5Ÿ¯kmw ºRú‹.f EbJ RˆAbT–Tv¨$88Xnúé§Ÿ:OÌ Ë)þ>~üX²aêUI)êÙÑÑÑÜÜt¢ô&º;ÈŸ1H R‰AbJ ŽºÊÞ¼ySŽZ§²p¾rå Ö¸|³(AÅ«Ò8³zîÜ9©‰Ýn—”HJzzº‘¬Nš4 ‰Ó§O7~èÐ!œê‹Êæææ*7&•íG¸¯ì¸“Ž{-ÑÅòêÎZ›PÃH¾Ó]†Ž“DW¢Ci­‰A*1H ƒÄ / ïYÅ… b),V–ê’TÌ‚bbSq§L™¢ÔÿO:UK¨®®F rJ&K·lÙòèÑ#ëå«ìÝ»wîܹ˜M•CLÀJfÝ·L¯.Y²dñâÅ¥¥¥’‚*™)«”€l7ntK¯««“’7oÞì‘Ê&&&"‘T–T–o Ï⼚³?{˜h´conS ¤7+:(Ú±G» ݇N¤µ&©Ä 1H ƒ¾+¦¿¿¿I2“7á]]]æSÆu¤fï.&E-–¯òÙgŸ _½zµ\ˆ¢té¬G7`·Õ³Èß$d, E~lðpTöåË—]¿ 6©,©,M¸ièvÅ:C VáפêU]´—Þ£èt ºF» ]†Ž£µ&©Ä 1H ƒcFHe!˜5£ÃdiHHˆ¤`¤Á1×*‰øyÄUXR0a›””tÿþýk×®i”&LlZ,¿/*‹YVüÿÅ_455aªV¼…ñwþüù¸‘^7c¥£ð4ž9s¦Lãòèèh3û]ºt©”óäÉ3•5ËñãÇIeûRYʽ'·r5ƶä?Æ”ìËkÎ]ÓEEÄ8ö¡;¤_öfþ‚nºûä&­51H%‰AbcB*ûùçŸ{Œ·6Ø×ZÙeË–IJQQ‘&>xð@Á­—/rýúu°Vu<Ûf‰óä&/^”lqqqê´lÎ÷f#[ÆfB’^^^ŽCRYRÙ!»/¥þzù©Ò:êyÀ¾!®"<·9}$í ŽfGãkGœ*Ý_ßUFkM R‰Ab$ǪÊÖÔԸ킣S©}QYñÆ.¯ne9rK^wìØa¹|Ïbd°?üðCV¯lÚ´IåÂûÙ°ë¬q/YÄF¬cx>øá‡’¸~ýz)ù¥Ì;wâT–TvàRYYé1rûqwvÃù=«Ô„øÙ-Üu¡æTɵ‚á0ZT4,šŒ¦Öfß“ñsÖ¥xtÇX²¸Ä 1H ƒÄ •4 ©,»Bl'¤Ãé×#•ÅT§"®Ò Ëï¿/ AAAÆôƒJúîÝ»%X”ú9cݬfƒÿ°.ÐE€egñ=†ã1IeIe)Ã+M7kÝþpî5*Ð=™¿œ( ÉhHªêrÑôFÑ€hF4&šÔØÂGò¶fÔÇ5߬õþ_¾ƒÞ?ÿó?'XˆAb$©Äà€…T”Ï| 3«8Âé‘ʶ´´È!vµ’òÍ‚«döÕmó]£+±ŽO:%‡X(ëV¦|圖###åìåSñ› R”$ÆÄÄàðêÕ«¤²¤²”!–Ïî¸Ú â+ÂÓWÍÁÜ-ç\‘ù-™ÖíÍ…FCÓ[20}åùŠðÊöÂÏîúÐqÿÞ?üáÄ1H ƒÄ •°Êb>Ó|ê“O>Á©?þØ#•¯Ãÿê¬;øòÍ‚S}q]8ëî;ùùùR“ÔÔT·l6›MC%Kتþ嫯¾"•%•¥ ëv|­ùM)²#Ÿê¶ä-ˆ °Õ›ý²­¢Ã)把¦°7Ù«bÐ8h"4”±ÝÐŒhÌÎ{W|ôÇ€Õ ï·ß~;˜B(Ä 1H ƒÄ 1Hã»wïJŠîg#“¢+W®ôHe1S*‡³fÍr+300›ñlذÁrùž‘ŠûšÑ•Ýtÿ_¹rEnÎé–íüùór yöïß?Á$ºÿàÎÒ¤²¤²#!”¯Ÿ#¾­öThεIªiËäo-;œZ®èJN]wíx0ØxL<,ŽÇG#˜[Í…Fkè®|ùú¹¯ÿ~úé'€ñS…$‰Ab$IeᦋCs¤_üÓWØ'|’”/^h¢nB»víZ‹å÷?TÉËËÓD]àªÅXø*¬Ø<Áûå—_JNÙ’Ç,ØXˆkeIe.Øjð…P^¾~QêŠky0NÇŠv¤-3›®}ÙëŽïI¨ŠÎl¼PØš]ÞQêë€Áãà¡ðhx@óS£)ŽïN­=]Ñ–&zõæÅXêw˜ðöÏþ|fˆAb$‰Ab¤p_Y§Ó©\.Á2W‰Íu$Q—¤VUUI z%å»ï¾“@JÏž=ûæ›ot‡ëåëî>ØzÎÃrˆ2e?0U¥šíííÈ#×êûS—¼þòË/¯^½’DݽV\ IeIe‡Xþ§ÿé¦[Sî?½}ùF¼†ÎU„ÌÙ(ö̬»ÓW ÚþÑÂ'KCâ+£luqðËr\Í«ìôŠíéQ TUBÅP=TUE…Qí¾ž{®âFà/´"Ä 1H ƒÄ …TVH£øîŠdffjNõãÕµ¯:í)òÑG^jXcëå« š±¤›»B@k×b»Íog"F@†…*CÀ{Ÿ?N*K*;ô‚ˆs¸uBBÂp߈òúÍ«ÎûW3#­.6Öž¿]69èGw¤üˆ† Ux¢ôÀé²Cqåáñ®H,CB¼þ”º¸´úøÌ†¤ìË)¹Íi-YÅWrÊ¿¬Ýáê,«îrÕu×@ñ‘ˆSÈ€lÈŒK2—§ÔAQ(Å¢pÜ7ÂípSÜ迆x<…Gþz#[`SˆAb$)Ä U¡ÊNœ8144T‰¨UåŠ*Ÿþ¹fP¹yófIQÙ¾};\ŽP>VØšÛ…enÖx­›Ë±l—f·š,X°@7ò(ˆlì6ÕlŽîèè HeUd¨Q ˜AéyÛƒ@…÷Z®»œWíØÄ/±2ò¸cïÁœM»Ò~‚uE5PT CõPITþQ¨6*Ï$‰Ab¤ƒ”!RYqè-++Ã$daa!6eõ˜¿»»»®®îÖ­[ÆDL{‚p&%%anóñãÇVË·, ̘>‹‹‹Ç?(§Ÿ%`¹Xd[PP ¦(¤²Ã%Ø» ·þçÿüŸs¥w®;ºóäÆÕ;5%e×r­™ͶœÆÄÌú³X‰t¡*ú¼ëh\Ù¡S¥û£‹ƒ" ý± "IìËZ”¾rgêÒíÉ ¡øñý‘j߀ ÈS„Kp!.G!©µ§2/ËiLBá¸Eùµ\Ü7½óøÿgïaÛ0Œ†ºœ\¥ri‘Ë‘9©9i9qi9Š9 '&ááR¤Ð †Dò¬Xª&mëR¥77Ù{¨š¢,`ŸÜŠ}߯ÇQ ÁÔ4¨A ¢ALÙË|ÿ¦ìDŠ¢þöÅbÑ'h4˜²¦,¦l’ÁBºM¨ªªm[ ‚Aƒ¦¬)‹) \Ò‰ð!„Ð hД=Ã|>›šÉßSÖ”§wø:â44eÁ”½@]×C°1ƾ44eÁ”ýò€õz=;üÐ š²02e'÷úúê@xçB¨ëZƒ AР) #SvzOOOÃ')˲þàû‘Aƒ ASF¦ì—8)>˲áÃTUÕ Süú˜²ÖuÝlðϯâ€AƒÀ 0eÏ<+Ì90jÛVƒ AÐàôSö”«xŒÑs/p;PY– ~Õ h4˜²@š‡4æy>´™e™c?@ƒ A =S8û4Ž1Ìãv»í ‚$LÙôß0ÉóÜÍü'bŒC•IÏÍÓ h4˜²É5M3;º»»kÛÖíC\·õ‘!= ‚S6ý30B³£ÛÛÛëxh±\.ÓÿcÖ h4˜²S_È‹¢>ð¯ÿW7ü‰»)¸”s^^^ß~%íÓ h4˜²Óûí¥z|ÌÝÏÞ?öÚkv»Ýéïs8öûý§¯‰16Ms ßÔ 5¨A jPƒ€)›@Q!—„Ó_óððpss³Z­þú>÷÷÷ÃÏ›ÍæS>×®ž¾¸§À=NùÓ¼çÜ78eÿ:;;£úÌŸöÏÎÎ",‹é°··7ÂZ­öïc½^Ç–––°A°A§¬S–<555Eõ???éðøø8ÂÅÅÅtX("|}}m$ÍÍÍ‘|'€ ‚ 8e²äããã#zïèèÈäûûû‘¯®®¦ÃþþþÓÿ‚ÕÕÕÉûû{Ø`>Àœ²NY^^^¢÷B¡Éwvv"ßÞÞN‡ÃÃÃ><<4’¾¾¾HžŸŸÀó6à”uÊR­V£÷ñññL¾¾¾ùÞÞ^:ðöö¶‘ŒErss“6˜°A§¬S–J¥½—J¥L¾¼¼ùááa:œœœŒðúúº‘ÌÏÏGrzzš66à”uÊ’µµµè}ww7“—J¥ÈONNÒáÌÌL„———dcc#’r¹œ66à”uÊ’ÙÙÙèýââ"“ÏÍÍý7/‹žŸŸ7’£££H–––ÀÁœ²NYò144½ßßßgòéééȯ®®ÒáÂÂB„•J¥‘Ä7D255•66à”uÊ’îîîèýíí-“OLLD^­VÓáÊÊJ„äññ1’ÁÁÁ°A°A§¬S–|´¶¶Fïõz=“ŒŒD~ww—7773(ªÕj‘ôôô$€ ‚ üINYòöõõ¥·µµeò000_zzzJ‡år9­­­FòùùI{{{üÎ 6à”UMÂÿeƒØ 6ˆ NYü Ç"lÄIœ²êAãäÔG#hpÊâýh q4¢q§ì/æý q q4‚Ƨ¬zÐ8AãA〟NÙØ;W›Ï?ŽÿþUUªR•J¥R)¥¤´Ò’n’H‹h"d2ˆ‰Í6,X4„‘s¹0× lè÷î¾óéô|ïý:»›ãt{½*ûœçû=眧·÷ó|ÎçùpË;w|D{,X° ðò9sæ¨1ç--Z´(yÅŸþù¹Œ3æåË—ùßÌîÝ»ÿ÷.úöíûìÙ3÷/M#|ùÍ›7±p@ƒhÐ Dƒð¯`)ËðÈÕ† þ¤8ñðáÿÿþûAƒ)Zí_~ùå«W¯|É… Ü(KvKÂãÇÝ¡Y³f¯_¿vc×®]ÝØ¦M›É“'/\¸pâĉñ[¶lÉZ¸ÞC»·4oÞÜfðàÁÏŸ?ÏZ¸zV¼Eå÷q‰>i‘®×jW@rŸ:¼xñ 4ˆÑ Dƒh> ,ež‘#GúOe:íܹ3é© ±ŸMbϲ47Þ¾};³n*“N LÉZ6õ`Ó¦MášY ?þ|29PÿpÓ &d_ôäÉ“Ù4-}:‡±# oáz•ä)Ï]Z´há‡ÆÂ?h ¢A@ƒh KY†Gv©JzüÎmø_X»‚Ê9YUaÀÚÞã–:S’zõêåg>|˜oáæêÕ«Šs»ÃÝ»wó-<¹áþýûláBybî0}úô:;h‘¿¥â-ÜS“?þø#.l0š]¿~]{®PD DƒhÐ `)Ûh†güøñ~ÚLå冹Åè3º]uJ\u3¹Cü€ h=Š0h ¢A@ƒh€¥lc•òùýÿúë/÷ìÙ³g4ªœcbÕ‰µÛ<ËñŒAÁi…‡U—¿Á.\C›v _¹reõ[dɺ•l>Ù³Ô0 ×о»ƒò—ܨLøåÖ­[µiJ3UwŒ]LõYøÌ™3ã |ò䉾䃪†ÞŽÊ"qŸ@1x·ÿþûïŽL;­´±¿ÿþ[w[¶l™;ÌŸ?E A4ˆÁ A4Ø–² Ox¸{ç%²]Œ°‚•ëdƒÄªÓ˜ÜAIYÿË ÛêÕµñFó‰jáQõÑ[klá9(ñIÝŠ´på2}V€ÞdaÝH­—äŒé«°©Gü»[·nþ€~{Y ÿä“O"š:t(êXFe‘¨¸êFdµy ”£UØG‰Ujüè£PDƒh Dƒ`)Ëðœ9s&xç%ÞýÛ~Œ¼- ͆nذ¡Îh®Â¨š¸Oà½1GŽùGþé§ŸÖgáMÞ-1±ˆm3 >O¯S§N~EሾÆ’[mܸ1NL,} ÛUˆßí?üðCdU³éèþýûÛ·oWšSعÈiBÅG£}Uþ!e:)aIÛ8R¯Èh´zúŠ|¤^r æ.Qöcl"*|¬X±"§r£ª,ê˜û#FhzáT±°ð8R?²Â’£ù£Ð¥ön%~e—郣4ˆÑ $ A4Ø–² £˜2§üþgÏžMÊ$F,ÖéFÞeYUù6™=¤Nñ]_8mÚ´"-\¡Vª&ù'àÇtA¶GH©hqžžÞvœIl¨ÓÂ/_¾6øC……—dôn¨(R¢¼¬Â<.ùz\hF¥³ PDƒh Dƒ`)Ëðh‰+å)§¿6Ÿ$‡QZPä0Qmt)죣ZÕ²mÛ¶úΠ‹Š…EZ¸.©‘oá…'.È;\¹qöìÙîàcôUQCm¨KëÁfŸX¸ŠR؉½ÉjÊ”)úDú° Ng-<¶W)¥*ÒáÜ!ð=ã3fLëÖ­ÃÅõØÙ_( ¢A4h 6€¥,ÃûO†Z_gå_9Ì©mBqÎ[pñâEßA¦ë¬*ŧåu àkþ$Ý¡H ³ãd¢EZ¸nç4ØÂ÷ìÙã*\éƒü§6,e³ÑªkyúôiÖÂUbѪ~c\Ç „C'•3röœI#¢ûÇ׫W9~üxôwÆWÌÏ.]º„"Ð Dƒ Ð l$KY†G6 —/_^§k?Œ;ÄYçA”tÚOØL¶_Ey\‰}&õ*++‹±pÅn“ƒéó-Üq?«¹Â¿9O/ŽÔ! n‰ãà“SïåÍQ $ká?ýôSRÄÂ(µ,±p£m?. "â`údVáƒõíŒr»êˆ Ñ 4ˆXÊ6žá±ó™Áƒÿú믊nª]^«<¨ØW#Ÿ®ïH÷… ºQ|:ÛG¢þ}û|+Ï!”5¤F?«W â„{ß"WS»g ±Q'káz?îoÔ)U1i°…Ë&#úîÝ0 `j¯N`t_59ê×­[ç “ËMUUUaÁŒ(F¢Ü*7j>¡nw0E A4ˆ ¢A–²jxXµßÔÇ€d09eÝ-¿r†öÿ¸Ñ–¡`b^há9ÈõŽþaáùÌš5ËI_ ¶pUp‡ðf°6ùÄ»RéŽØü£o5jQ&.[u„ÞW©^HËu•£T£-Y-q`CvW\®ïYYg¾‰'( A4ˆ ¢A–²mx´Ä[Jd3?þøctË·gG‚³Ï† )´lJÐK'yD—Í:·f rbÍŠ9zÞ>*‹Õ&(GpóQô:›×”T€t‡¨êá@r˜h0hÐ §T%éOq6€ÀÂì¬WG(roÖŸYŸŽ@xà cÏ Ã+ð" DƒhÐ `)Û8‡G…T8aÙ²eªO(˱Mþ·è%´+FYC3fÌPuþ­[·ºŽb#àîÝ»*稵~ýú"?”òÊ4Юà dÃ…~íðqÜ:;­Ñ ¹%¡¦¦F¹p êë=¨„£ŽL@h ¢A@ƒh KY†>$JEó9þŒ84h 2âÀR–á)k@ÙY*@¢³GM‡ 0âhÐ  A4ȈKY†§¬´ Á2]»veÄÑ  A@ƒ  °”ex ôÞ¹sgÃ`ÄÑ  A@ƒh–² O¹*ƒqõêU”Lj£A@ƒ€Ñ #,e`ÄFœF€¥l áûFœF`Ä€¥,ÃSV#Έ#Œ0âÀRø~q`D€F„`)ËèpðàÁÊÊÊèñýû÷õxáÂ…Œ80"e¨Á¸lLéaÄÑ |óæÎ†-—`)‹…ƒ¸Ó7¹bÅ =^½zµwéҥΞ3gÎÔ³ƒfÄK Dƒ»víêÝ»wóæÍýëAÿþýï޽ˈ—4ˆµ‚={¶ÑiÒ¤‰žÒ¿mÚ´Y¶lÙË—/qø`°”ÅÂANìoòúõëúsÀ€z}ª}tÿôªo¾ùF_ã¨Q£ôøôéÓþ©'M» XÊ,­?ûì3µˆãÇ»Åôë×ÏíZÙ¢Á÷Dƒ={öT‹2Š ·©ß¾}ÛÉÆŠ+•ш°”ÅÂóÓ¾ýö[Yš·« 6LÚ h½%"æÏŸßªU+å#)U©¢¢"b½fóæÍ¾Üè&sæÌ)œlÙ²E—·nÝúÙ³gÑíº6¶îtìØQAâÇ/_¾\{xâ†Ó§Oç5š@ªÅofÒ¤Izˆß¤kBì VןkÖ¬É^Õ¬Y3–²€K©ÁK—.;w.›œ9bÄwÖïQh°d A|Pܸq£oß¾î¹qãÆrq–²)Xøµk×üŠÝºu+¬X¨"‡õYx÷îÝUõ7"¸rJµ™ÇnW7÷×Þ›†Y¸~Ÿ‰nšòzÁé­>ùx6 w7ß— Q^“Ÿ’yçX¸Ž¼«ÓÂ59Hn¨20~Jqn·$gx´«% ?ê±bçž"û©+V°”4X&\µj•{ ½•U#4X ꜡yóæùþ ðå*7… ¼`)‹…'Ìž=;«’=BnÏ·ðði9hrg§WøTXx2aíÒ¥K®’nɦ`éúÂöä òñÛo¿éÏ¡C‡êqeeet`) h°4¨*¯Q ÕÛùJDƒh0>ò£G’ËOœ8á§Tè @ÙÁR ONf÷+*®œú\®…GAÅ8À ¹s= ¶SîÚµ+{ƆP‡úÎÓ‹³ø":o >ª««=9öŸÎ]T#KY@ƒe¥ÁAƒyÏ¡gÛ¥ ¢A4¸uëV¿„ S%—+ÚO={ @yÁR OPZfi¯•ËÊAåÊÞù“oáIjV”µ0‹/v£®J̾sçÎ>®àâÅ‹‘•XxL œ…¥79|øp7.Z´(çãL›6M}„öÁ•þ\ Q³”4XVôþ=Mô÷Öí[·Ð |O AÝ3÷ïßïÆW¯^éÎqj.b@ÙÁR ÏÙcWK¿ÓÂu$€ÑaàN:ye舲œ;zv\’cáa¨ñ®***âп ©6g»Û’ûôé£Ç,e –µLU{>ZH A4øž@ƒ‘íS‡9~pm(Ï`)‹…§¨€„Ü1P$Ÿ¥K—¢A4ø^Á7mÚË×àã?Vä²q–²XxJ$©”¿Œ°0púôéùW…õjÏÛæÍ›,X°oß¾œ"þzjO-7oÞ¬ó>±gÉ“ƒuëÖmذA“ FÐ Dƒh þ‡(ÏYužT¬Xy;vì¸rå €r†¥,žÆ¡»Ô¢£ÑxüNôûI ?}jáŒ8 A4ˆÑ dÄXÊòzJà®4ª(Ê_SSãP´RtŽ…£A4ø~Aƒ€Ñ KY†çŸ2vìX¿¨P÷ÆQÿéuÉÀ ¢A4h °”å?ôb]Sµû“RŠªKQUU}Joá«V­bÄ ¢A4ˆÑ #ÀR–ÿÐóxñâÅùóçwïÞ}òäÉÒœ&(‚AƒhÐ  A`)Ëð@>ÿgï@£.8ŽÃô‚Ò Ê6+ÙIN“ÜTjÊHE5cÕйJ/Ì¥`S7Ù »¯R7)™™â¬$—JÎm.MWãÒRGª³l9šK¤­ÁÐ ž÷/Àîù?w€÷ý~ö;{øqüäîÿpâàDÀ‰s"àÄŒSÿKï8qNœ88p☲ÏÿÐAÐAÐA:LYW|„ƒpÐAÐA::€)Ë”ENNŽŽ8Úc÷¯ì»råJ¬@ee¥UUUf8úëÖ­[ :8B¦,S©©©:âîîn{,==]±?þø#V  ) j3œíÛ·ë¯ëׯ7èàHt˜²LY è|}>Ÿã'ý­[·btËŸeeef8ºpO-,,4èàHt˜²LYtttè|333=“ÉÉÉJöõõÅ TWW+PRRb†ÓÜܬ¿Î;× ƒ#ÐA`Ê2eñÝwßé|óòò<“£GVRWÒÇ ÔÖÖ*P\\l†ÓÞÞ®¿Nž<Ù ƒ¦,S#QWW§ó-**²ÇôÉ­˜>Å-™(³bÅ 3œ¿ÿþ[}ä‘G :ÐA`Ê2e1ápXç í1}ŸJ1}·Ê’ùòË/•Yºt©ýÿ³ïÞ½kÐA€S–)‹„•––ê|#‘ˆ=¦§\(¦'^X2_ýµ2~¿?Và‰'žPàÏ?ÿ4è @€)Ë”E–-[¦óÕcí1Ý= XFF†%óí·ß*³`Á‚XéÓ§+ðÓO?t ƒÀ”eÊ"a³gÏÖùž>}Ú»|ù²bºÞ’ùþûïíOÎX¼x± è 0e™²H˜þƒYçûûï¿Ûc?ÿü³bÙÙÙ–L4UfæÌ™±@@O?ýÔ ƒ¦,S KJJ²_- ÒÚÚªXnn®%séÒ%e¦N+°qãF¶mÛfÐA€S–)‹ÄtuuépÇå9ƒƒƒú«žiÐA€S–)‹ÄÌŸ?_‡ÛØØè™üàƒ” ƒöXrr²b}}}±ú‘===è 0e™²H@VV–·½½Ý3 …”¬¨¨°ÇRSSíŸÐS¦LQ@7ït ƒÀ”eÊ"z4…···×3©o%«ªªì±ôôtÅ:;;ct#ŸMMMè 0e™²ˆ×;wt²))).aÝç®°¾^e=ýôÓŠ]½z5V`ùòå |öÙg¼ÿè 0e™²ˆÛÅ‹u²ú¦“KXºP¸ººÚ{öÙg»páB¬Àúõëؾ};ï?@-:LY¦,lµ/\¸Ð%¬ëÖUöØsÏ=§X[[[¬€¾š¥@yy9ï?@:LY¦,âV[[«“]µj•KX—Â+¬ âí±^xA±S§NÅ |üñÇ ¼ýöÛ¼ÿè 0e™²ˆÛ–-[\Æ(RPP p}}½=¶hÑ"û­GŽQ ??Ÿ÷ ƒ¦,Sq[»v­Nv×®].á%K–(ÜÐÐ`é³Y±cÇŽÅ œ={VÜÜ\Þ€t˜²LYÄÍï÷ëd=ê¾y@ss³=VXX¨Ø¡C‡b®_¿®@ff&ï?@:LY¦,â–““£“F£.aýÿ±Â­­­öX Plÿþý±ÿþû¯=ôï?@:LY¦,â–ššª“íîîv ggg+|þüy{lÍš5ŠíÞ½Û’;v¬å>úátt˜²LY èX}>Ÿc~Ò¤IÊ_¾|ÙÛ°aƒb;vì°džzê)e®]»f:H:LY¦,ÜuttÄõ[ŒŒ åoܸamÚ´I±p8lÉÌš5K™3g΀ÒA€S–) w---:Ö¼¼<Ç|ZZšò·nݲÇÞ}÷]ŶnÝjɼòÊ+–û †ÐA:ÐA`Ê2e¡KÞu¬EEEŽùääd—ö¼÷Þ{Š•——{þŽè£>2¤ƒ¦,SîÂá°Ž5 :æ}>Ÿò÷îݳÇ"‘ˆç?[YY©Œ.¦7¤ƒ¦,SîJKKu¬úÄu *Qþ­·Þ2"^ Œ7Î{ÿý÷ ƒÆ@é @€)Ë”EVV–ÎTW´;ækjjSÔß߯ä˜1cì±}ûö)¶råJã ƒt ƒÀ”eÊB±:ÓÞÞ^Ç|$qüÏã¡¡!%Ge}óÍ7Š-Z´Èxè è 0e™²¸sçŽ4%%Å8 …BzIyy¹KøPøÞ½{–̹sç”ÉÎÎ6ž:H:LY¦,.\¸ 2eŠqVYY©—TUU¹„SRRîëë³dººº”yì±Ç @é @€)Ë”…ãåx .4ÎÊÊÊô=£Â%œ––¦pOO%388¨LRR’ñÐA:ÐA`Ê2eQ[[«]µj•qVRR¢—TWW»„322îìì´ÇôtGOz€ÒA€S–) ‘-[¶è@+**Œ³Õ«Wë%úìw Oš4Iá«W¯ÚcÏ<óŒb/^4¤ƒ¦,Svk×®ÕîÚµË8{ã7ô’¸„§M›¦°~‰dÍ›7O±¦¦&ÐA:ÐA`Ê2eaç÷ûu G5Î ô’Ç»„Ÿþy…ÛÚÚì±¢¢"ŽÄ÷ëájiölÚDÌÍÇ~ª®ÑLY(õ˜[wú¤€®íÛ+ý‚5«Ä÷›á°4·&Æ‹âãÍ5š) tPSÖ pëÂ}iJ§”~ö†|ñ³<,Í©«ßüüÖžS–B˜²fgGÉèÓ­«Ò—¿»ßmÒ$K³dýZ1=¦LæÍ”:¨) F¸|ê†4¥‡kO¥/û*¾cêLK3oóN1gN›Í”µk!LY0ÉÝÂ9CúôVú§³·‰ï3ÚÒ¼²{§˜c äÍ”:¨) F8sø‚4e@ßJÿÀöbñ'Ž›li9pRÌaƒG0eíBSLru÷.9c ÒÞ5wnÂС–æ«ÇÄtíØk4Sè ¦,áhÁ{ƒsøíà<´ï˜ø£†±4¯—Þ³K§.LY»†”“”æåȘ:r¤Ò¿µŸø#û÷³4póº˜ê×çÍ”:¨) F(ÜuHš2nô¥²¤TüÁ‡Zš¯|Ă 2eíBSLrlË&9òý“JÿÑÁbñöè¡‘«W«&ò¯=àÍ”:h SŒ°;g¿ÔD¾VéŸ?vEü>½újäjeüêËo3emBSLR¸vïéÓ”þËãÇÄïÙ¹³FnÓ¢…È_½pžk4Sè %LY0BÎÆíR“93œJÿÚÙÛâwë⪑[µl-òÃkϘ²¶ !„) &Ù•ùŽ€sç(ý/–ž¿“K[< G‘qfÊ´„) FØ´ê]©‰·›¯Ò¿{ù‘øíÛuÐÈ}zö¹ôè%¦¬-CaÊ‚I²““äyy)ýo^¾(~ëæÍ5ò´Q£D–\åÍ”:hSÖ°*}Ôd¾ï"¥ÿäæ+ñ[¶h¥‘'Œ™(²|è± §,!„0eÍb¢åDÌ Pú?¼uCü& jäù³g‹,?tâÍ”:hSÖž)5Y¾0Hé¿~ðEñ5l¬‘=>"Ë~m8e !„)kX& aé¥ÿ‹÷įS«–FŽY¸PäUosfÊ´€)kˆL’š„F(ý/=ÿ†øµk×ÖÈÁKÃDNŠIµá”%„¦¬Y 9p¹€ŒÐ¥ÿ‡gOįR¥ŠF^%räüy\£™²@-`Ê"B¢¥&±o'(ýo~öûo:¨‘Sã2D^¾(؆S–B˜²fè… ä¬ŠÔ?R£zuyä7Zš{Wf‰é?s×h¦,ÐA ˜²†€ %¡R“”¸tý#5ª×G¾öê;–æÖµ9bºÏö´á”%„¦¬Y Ô×GÀÖÄxý# êÕ•G~r÷¶¥Yš—+æäùF3eZÀ”5, X"5ÉJ]­¤~½úòÈçÅÒ,ÚuH̱£ÆÙpÊBSÖ,°ØÍ)`{zšþ‘MšÈ#ß½vÅÒ||¨D̾®Ý¸F3eZÀ”5øzHMÖgmÖ?Ò¬i3yäÅÝÏZšO\³g÷^LYBS–)ûò |TLlï" aØ`ý#-êÔ‘G gN·4Kf;Äl\«–ý_Ért§ƒtÚÊʃðQ1´çh©Éâ™áúGš4h&¬ ʱ4×ç‰Ù n#Û¿Œf0!„)Ë”…‹^ngÝçè}—úõäÌìuL±4/x:Ŭ\¹×h¦,ÐA:È”-·äÅ”l‹< ÷[6n-ÍÊ\ºÙÒÌ).ë`e¦lY!LY¦¬Ñ_Œ„¾ÝºÉ™yzäFnÚ¨‘ÅoB€_Œ¤ƒtÚaÊÊ1È/ K­.Ÿº®‘›4n"òó²ßF6 ¿œLaÊr†¡}zË™¹WT ‘{vî,ò󣇹F3eí¤ƒLYÐw Ôêìá ¹[W‘¯œ¾É”%„S–k4Œ4HÎ̵=»5òø!CD¾¸#Ÿk4SÖÐA:È”…áCFH­ŽœÒÈ#‡ùàÞ£LYBˆá0e¹FÔ‘#äÌœËÏÕÈÞÓ¦‰\°f5×h¦¬= ƒt) ãFOZí>¬‘çÌpŠœ½!Ÿ)K1¦,×h˜=~¼œ™ã[·häp?‘7ÆÅrfÊÚ:H™²0uât©ÕžÜ¼dþ2‘3’²˜²„ÃaÊr¯iSåÌ”¬_«‘W„‡‰œ°t ×h¦¬= ƒt) ³s¥Vy›wjäøˆ$‘Ã#˜²„ÃaÊr†ù³gəٛµB#ç§§‰¼ØÍÉ5š) t2eí§Ó[jµem¶F^·b“ȾþLYBˆá0e¹FÃ2O93yi©Y~Rä™ãÆrfʤƒLY{à½@jµ6s£FÞ“{@äɦ2e !†Ã”å oþôns|œF¾Sp@ä!½{sfʤƒLY{°dþr©Ufò*|úÐy‘û÷È”%„S–k4Ä.Z(gfMd„FþRéY‘Û·nÍ5š) t2eíAȲp©UrlšF¾wù±È.m\˜²„ÃaÊr†Ô @93¡!ùî‰\»fM®ÑLY ƒt)k"Cc¤V1oÅkä/=û†ÈµjÖbÊB ‡)Ë5²Þ _ˆZ¯Nñrç×h¦,ÐA:È”µ QÉïëC‰ëÖ©+þç…)K1¦,×hØ#g&bþ<¥ßÙÅEüÏ>É5ú‡dÊ~áé×äWU¿öê;LYã¤'®N-_¬ô;´ë(þ­ ÷™²„“aÊr†ìä$93ÁÞ^JD¿~âߨ·‡kôû :È”ýÆg¿—›Þ¹cçJKÿ>˜²fY•¾NÞˆ~‹•þàCÄ?^t†)K1¦,×hØ•™!gf‘s®ÒŸ;q‚ø‡7màý¾B2e¿ðä«ãGO¨ôaÊše㪭ò.ø¸û)ýé“âï|w/S–b2LY®ÑP°fµœ_‡Cé/÷ô?;%‰kôû :È” ‹­TùÈ܇מ}õå·å›]† Ê”5KöÆ|ySœ³Ü•~€ÏñWg¬cÊBL†)Ë5ŽlÞ(gÆ9i¢ÒO\.~zH0×h}è ÐA¦ì“›/+•ÅßkÞ?ÿÿŸyø%¦¬YvnÛ'ï‹cÊL¥-~txS–b2LY®Ñp&'[ÎŒcôh¥¿51Aü`oo®ÑúÐA ƒLÙ7?ú“\/½Ã'—+ v”Èû2qìd¥Ÿ•ºZñ·µLYBS–)«x> ëÇ‘3Ó¿Es¥Ÿ:b¨øcÚ¶ù?ÐA ƒf)‡S6öíyãš6iöÑ~<’(Ÿ4ykº·ï­ô—ω ë°ÿãÀÇ^9BS–k4œuŸsÁÓ©÷7–]»û4kª„k4:È”õrú¼ù¼âò6ea[dA^L‰ÞöM—·²«K^:¦,!LY¦lEúÅHx}ò¸œ1×”þ§ ³S–ÒA(·Sv¾ïByãºuqýSÖø/'ÃÒ»òVvîØ…—¢"ýr2!„)Ë5~x놜±FõëëáM2eÓ2ÿÂÞ]ÀÆ•ÞkC÷¶]r¸‹ŽÂ‰ aæâò®ÃXn˜ÃËi&ÌÔ¸a²7±ÂChÆP™»ŒÍ(–Nì“sfü¼z$yNùTŸôýÆ ìÌÑl(Ò8ø¡¤ûï€Wb”eŒAY®ÑT¢xqIÿ>|ðŠçe‰3eoüÝB¶)c}yŸgœ<r”¥ÅKH:s,›WeCiŒAY®Ñôp¹r’Î&nÉ}BPöÆgÊfú/Ô¨ZSÒ=÷Ü»1>1ø0˱C\g(r}¿üƒ’ì—ó* Œ²Œ1([´hQI_}õ×hç¢Ú5ªK:°|éÏ ÊgÊÞ UKÖëò¢jF7oÒÒX+ ʆ\öŸ¤ÍØÊ«€²Œ…ÍŒ’Œ“®Q¶D‰’>ÿüs®ÑÎE?iÚDÒúiS®xNP–8ƒPöÆ%¬Nzì‘Hå” ÁZ5o#iѬe¼ (6cÌ)É8ée¿÷½ïIú裸F“suú)IsFºâ9AYâ BÙü›c·oÚã›0{ò;ÓM¶§Ò2¡lÈüÕJãߜ̫€²a3ÆŒ’Œ“®Q6""BÒ?þñ®Ñä\C~ÖCÒ›ýû]ñœ ,q¡ìeC®^¿ì+éåÁÃyP6lƘR’qÒ5Ê>øàƒ’.]ºÄ5šœkìàA’tí’û„ ,q¡,”-þøã’¸F;e'm•T¾téÜ'eïZÄ„²¤¤ïßv$ýø9(ëV)»K*[¦,¯Ê263BJ2NºFÙ.]ºHZ¾|9×hç¢S“%)R$÷ AY§#Î ”Íô_6tdÅ uy±Qµ ¬+eù/Ï ¯Ê263BJ2NºFÙ~ýúIš6m×hG£2’ÎmO ~$(ëhÄ„²$ŸmÙ´•®”u«R%KIJÛ{’We !%']£ìèÑ£%5Šk´£QÍJ%¥®Š~$(ëhÄ„²ƒú U`½~Õ÷ÐöÔ³Çr6¬L¨W»>”u«ª•«IÚ¶~'¯Ê23BJ2NºFYŸÏ'©wïÞ\£ZÕ¯')qÖÌàG‚²ÎEœA(›¼ë˜ëÜ®kÞç'‚²nÕ¤aSI+¬âU@YÆÂcFHIÆI×(»zõjIqqq\£ÚÿäÇ’–¼õfð#AYç"Î ”6~¦Û±y/ß`쑞yü9IÓÆÍäU@YÆÂcFHIÆI×(üåÆs¾•íGÏU®TDêÍ«(ð8ƒÄt7Rvhÿ—$•.UÆ_äs‡Që:?-¢"íZuçUtî0˜1f„”dœt²’"##¡,×hG‹úq^‚3AÙ+#Î ”m÷l‡à÷{‡²ô»Þ³x áDYƘR’qÒ5Ê~öÙg’Š+eCî/Œ$r—²œA"ÏR¶[Ç’ªTªêeí"þâdƘR’qÒ5ÊÚ|ðAIçÏŸ‡²\£ ʆÁ$‚²#^£ÀÎ͆²AYƘáQ’AÒ~v“²5ÊÇ_å e‰ ,gÐ[”]2{…›2Ö—÷yÆÉóP6ÿ”eŒ%$]¦l§N$-]ºÊr&(gÊfú/Ô¨ZSÒ=÷Ü»1>1ø0˱C\g(›ÿÊ2Æ ’ ’.Svذa’ÆŒB”åMe‰ ì Zµd½./ªftó&-µ’ lþ#(Ë3CX¯_õ=´=õ챜 +êÕ®e Ê2Æ Œ’ ¢ìüùó%uìØÑû”åMe‰ Ê&ï:¦À:·ëš÷ùÉC§ ,AYƘQ’áÑC”õûý’"##½OY®ÑDP–È¡ ì´ñ3ØŽÍ{ùã+"(Ë30J2Ìò_ì×Êæ ,cÌ(ÉÀèQÊú|>I:u‚²\£ÉëAY"‚²Öª%ëuyQ5£›7ii¬•e sP–1fH”d`ô(eO:%©téÒP–k4y?(KäDPÖJXôØ#‘Ê3([ȃ²Œ1C¢$£G)k«Q£†¤½{÷BY®Ñäñ ,‘CAÙàß»}Ó߄ٓߙn²=•– e mP–1f<”dT´Ÿ½KÙAƒIzõÕW¡,×hòxP–ȹ ln|ƒ1AYƘñP’QÑÓ”MJJ’ e¹F‡eKßyûí¶Î™ü¸{ÑBû8oÌh®ÑœAâ BY(ëÁÖ­Ø4lèÈ oM ~<´#Í>Z§Ó²x9w²Œ1ã¡$£¢§)›û+y>üðC(ëî5šÒßMX;eÒú©S ðß³iíÚ’úvîü8²WOIU"ãÍ$Î ”…²ùìTZæ‚K,ÿáÓõï9¤ß‹’*V¨ü¿hKÛ{2,ÿ÷BYÆ<8ƒaî¯áñ:e»wï.iܸqPÖÝk4Í=JqΔ%Î ”…²Þl×–ý lÃÊ÷)ëþÿ^(ËX˜Ì`(É”]½zµ¤¦M›BY®Ñ\£½”%Î ”…²PÖé ,cÌ`(É”ýüóÏ¿óïHJOO‡²¹F’–’¹õ[öÎFŽdÙÇÌÌf†ƒ033333ç²afXf¸0Ã13‹¥÷I–¬Võ\§n´ÙÉèÙ*EÝnw«:%ýÿÚåÚ÷ÖáC¥Øáûiñ½ûY^ιÝ;?ÎΊ°ùº¨àüî]Ñ6Ú>ÍÍþ² /ýMqá;©‡‹Ï\Å£¿(ÈSÇ¢Û™éL‹QY[ƒ¶m ª•=[|9ç`áåão•o9™þõSïºz¿jÌxr4ût„ͧß+L;æÉ1Æ™ø¨¹¸äåzÎUTöLáEÏÜ`†PTÖÓŸ×N½s4û”QY“ëP „,sè!$1 ¨,Ò¤I“ë$ÇØ`ôÉm[«>ýÔïû¾ò÷¿üøQv¦<½¸w÷½·ÞJ×£»óâûéiÞqæ Äm£Ê•¹^?uJц”šÏ='ÒÛKÕ«½—žêé̺ɓè„Enüï—í X¶Õ=r÷]A›Yƒ|[R¤‡—.¡“çy<¢s'í·VŽ#6ï¦A{òˆkž¢Ï[·–kƺíÓ²…<}ûÈ!Ÿ¹ò‡Ñâ¾-[¨cO>p?~:(¹Mƒú0üì5«î¼é&̺7ibTÖÖ ­A[ƒFeá$%‚zéÂûïy eù&5xö©çï¼í®ª•ª‡ß­^¹&×{‘ëaFqÝ¥]÷ã¹g_lØäßÿü7]ýö·¿ãõ=›zú|`{ê>¥žð:ÌðlÑ%‡•{¶Äæ¯ù[ëfíV«ZœY4kÙmG*•«"ÆXÖ­Ù÷Ćéa¼\`hG:ú—5åzÆ„9ð½[o¾§m[´÷œ+*»qÕVŽ5¨ÓhóšAƒI£§áFË&mŠÒ1Ìp&så £1–¹rä±{ïÕ(“öÓ¤f 50*kkÐÖ ­A£²°ÄçŸ.÷£Xu›æ/µMÖüà»™ûóD?¬ÿHnÛµè NùR‘Þ™qU‡çN]Ó“*ªV›%sV:O•ÐfìËÕ®„‚ +väž»î%¦ŠMØÏ){Ð?öðã\ÃåT•õœ+O*Û¯ûÀ˜ýL3Ýéç‘…srMe}¾Qìñzû[FîD”ðm£²&&׉@ Y˜Ð䡲ZÇøÄ‰‰š5ƒÑDE4nsdÙ’ÏósÉÙ›=h Ä‚›‰‰&gíšàëŸx<ƒÐWÈN,HYGü$^#ÚžùóôwÓV,#1?噾ܿhÜòÓG7o"às|ëæöŠ’ Š£% ÄQĵVŒ£$l¾+)"¼#áúÌÎí £ƒÚFtÈg®|`4¿«á¬ùÆ€æù鉽zjhÈÑ"µË=?­_߬Õ+ÊÚ´5hkðÿœÊöêÒW>J§¶]ó”\:ö&¡Hè“(‰ÔÉé2rKÜ5øîÀÞCDQ*+<²+“ð)O4M7‹ö„lU%¥Ëæ­"­7ïp1ATQ.»›c9g4¸iõvŽ·!Çxì°‰h„¸*ã*+2¨ÏÐìƒû¶&ê(š9S`Cÿ+¬ ,o¾RYeÑ#òùÌ•'•]½hh ‡{7"šw‰îŠRc¼ÒÒïþ=-™½"öìù}£˜ãõ÷G¨¬È¸á“˜RŒ[5m+âðו511 jíâd¢²;vÄoÃMÔÄŒîÕ¼Ÿ9»kGPO® èå„ 0¨Ü‚)ÕæÍÃE9¹OoFƒDƒ»ËDI._„'€KAÌĬª°Êë¦MÁ†È×ü(6ønÃʕČ=uA]îÑGÚjÙ¯UKÑëÂð>=œW´-ØÝ®|`4'^Šýιs‚ýÌ8@ôí'8ÃVöÉÖ ­A[ƒFe¡7òQH©uö¸Jð %Måz£6J+<_In•ÊÂÁ‚f¼¥]E4"Ÿò:¬L•§ .ˆ’bnÛ·ê3ö8vØÑCÕ* “ îzU.±wT©¬ÐBÿ¹ò¡²WN¼%ùÉÞÿ0éÊÁ~$%öîPÙšUkGo`öÿFáñúû£TvôqÁß%oYôD€NeMLL ƒ¬Gˆa’QÙ´´4ü¾ñÆ5q£Á¬|öÑ9zà#zdd—΢:ùó†›7&7:½ Ñ·¬[G·¨9 å¥}{¤·¡Ú‡3Ið#±Pm êØ²å°[`´Þ:›EO´êª0¼ß\EÃhb;§ G礟1ݺj?ò¢lA4*kkÐÖ ­A£²'å3¥îÎrA周~=É-‘=1 aX4‹g/w¨ì¹’+Á®Øí)qT¹½xô *›„R…8ät<™8j*1^b’\;äJ,Q~šDY'ÁرÚöBƒ—¯Je±„ÚÅ1WÑT–à°Ü®]ºÁé§}ËŽá~‚´£Ný'§¡ôûFîxýýQ*KTÜ)åÅFhœ'œÊš˜˜@YÃ$£²ÈwÞ‰ë{÷lü-I`4 {L>²dÔˆðS©ÅòrrK¥1&_1ò(-õÂhÙÞÆu8(¬Á%GÚhä¤vF ɈnŠÓF^¢oɳzŸCëld*Û³sŸÒ¢²þsMe ™Ê-Ó2sâܘ8g¸Í.ÖyÓF†¶ç7rÆëïN«µ‘o,=ðë ¤²&&&@YŒP¤¤²Hƒ À¤I“Êxî FS©E+:Š7®×‹*µriɦ Rÿ³GÓ&èýat„3%â8£N’ÝÇÞ6’++Ôvë¾è£Ò†Ñþså“ÜHÕgÇ£6¢aäŽJŃѶm Ú4*ÁÁ$Õ9ŒT#~ZI«×vmßCy?•>ÛV:ç´ç§ÈPF˜ˆŸP&¥»Îi´ÊÇ®•õŸ«h*«å‚¡ˆN?'òÎÁ?K¸|”GóúFÎxýýÑ©ãd Ç,ç`¡ô°õ•] ¤²&&&@V"dëd¥²;wîd ·ß~»jŒÊ–Y4LÇ)j2wÈ`ôrClH“ì;ݳWZ0Z‹¬bÔ+ Þ5o%OåºU½ºÎë*W–ÕGÙ™¥£ýçÊFã¼²‘`?yëÖŠ>eÊdƒÑŽØ´5hkШ¬Ccˆì9AN9óæ©ÇŸ êÙ‰*dU’„ è••Õ a„=±áºÁ3-†LÞ¬dÒFZ²n»½FTÖ®¢©¬?ê;¾U*WE^ŒƒÊz~#g¼þþèÔ…ËGëyK%™'HeMLL €¬DÈ`SYÆŽ;Êxú F“ª§Àôë¢QŽåðF`œcÏ<ôšž‡¦´`4SF‚echœ÷(}* &åØÐ(#J«hüa´&UmH‰€Ñ¾så£9ÁRú©þì3fe¨RFJoê³Áh[ƒ¶m • ÇB ²Ie öi¾(~“l¤±IUôÊÍJ‘Ê®^œ"ÝòëÞäØX!fº •Ôb­QÄ)2ZƒWÈ$T4þTV›9Î'ŠÊúϕǹ²äèŠfùüÕÚùà>ÜâIþTÖÿ…ÇëïRYæA»å|Z4:¥‰¢²&&&P? g&7•2e #©Y³fÏ Áhòë*?ù$“/¼ 8Ö[’ ûc[6ÉS„3KFð‘Ê¢¡§Çî½— 'HBâôÌɪO?%çs ü:=üP}~÷.nõGÃ0Ú®8ºà/Êq#ZØ&¾¹âTÏà&Æ; ÊÚPGBI*l›=3¢ƒÑ¶m Ú4*+²@ÊIݪńœlR'‚§­}«N1©,ñ=O*K0°w×~Ž'—L9æØõABK}ã`WBqéÍù ˜°Ö.rê!;Rö á4Z®aæñ͕ۣ›T7®Ú&fT·âVÙl…ç+‰^‰åÐ~#ôX§æõÂãõ÷GË>eõB‰EeMLL },F 40é©,Ò­[7ÆÓ±cG£² AKDZ-Y¼`ØÐsçpȇTCITLsÄ%žœØ¶EÓà gcnŸ=káða©Ë—¾Ÿ. øÛ›‡ݼ Ü\–sE´ŠB;œn²vÒJžýŒ¶5hkÐÖ QY åÙ•9oÚ"jÿÀÖ„À$ªQW –Í[A’Ú¹áv,çÌÆU['žÆÖüÔW…IÆÝ¨–Ä𥟲œ+*Ã6§ŽÁ($ªYͯ¿?Be©äÌõ¹’+ADv1ßÈÙ·ü?öîª?Ãø HP@ " &) ÒŠ±„ P€B€€ ‚  @$ d€B ¸0ÉÝw§Åîæÿ/3™súÝÏãÁ9ñå}tç^) <¾$ À>²ïÞ½Ë.Ÿ>}’²¤íI)KîÃÿIÙ•²ÀT4÷²Kp”-—.]Jrûöm)KšÑn”²ãI)  ¹—¤é×çqRöÅ‹IŽ9²X,¤,iF»ARÊŽ$¥,€†^s/IÓo¨”-.\Hr÷î])KšÑn”²{–üþY›ÿøç|R@C/I£¯Ï£¥ì³gÏ’;vìëׯR–œJ)KºA)KþÞ”ÐÄkè%iô ˜²e}}ýûO IYrr¥,9‰R–/e4ñ’4÷ú}ú4I{}ggGÊ’Ó*eÉI”²ä`)  q×ÄKÒÜ6eËÙ³g“ܹsGÊ’Ó*eÉI”²ƒI)  q—¤¡×ç‘Söùóçß¿ÊøË—/R–œP)KN¢”IJYͺÆ]’†Þà)[666’ܺuKÊ’*eÉI”²#I)  Y—¤‰×çñSöåË—Ùe{{ÛŒ&§RÊ’“(e‡‘R@ƒ.»4ñV"eËææf’«W¯þq3zšÑ`F»ARÊîñR–R@ƒ.Iã®Ï«’²ïß¿Ÿ$ßÍhRÊ’nPÊ’Rø¶mÜ­PÊ–›7o&9þür5XåM3Ú ’np°”¥”ДKÒ¬ëój¥ìb±X[[KòèÑ#3š×8Ž¿;®@>“ã˜2)ûú¾ìr¹¤_Àår‰¬ïû”IÙ·s>Ÿ#»^¯ép½^#;ŸÏ)“²oíx²¶mÓ§жmd}ß§Lʾwã8FÖ4;ïéÓØ÷½išÈÆqL™”ý¦i*Š""^^^ÖuMŸÀº®///QÅ4M)“²ɲ,UUEDY–ó<§À<ÏeYFDUU˲¤LÊ~<Û¶ÕuÙ0 é0 Cdu]oÛö{wPADAôK@‚‚ Œ\  áHz.«a¦ëù¨”}šÌZ«®Öš}´ÖtÕZÍy›)åœ÷ÞŸ°÷Î9ëzžÇ|¹1Æ!HŠ1Î9íå`Îc”Bc˜2OÖZ)%]½w{-è½ëJ)­µÌ™;ÿt¶”rαW€sN)åÇþØ»CPI¡(ã'нܢ=ÙÌ‚˜lF£lö틽‡Á"L/b³Ø-–³Ãp7,÷`fÞ ~¿fOŸWÿ÷|ääo/‚ †A? ÃÁÉ¿6=«ëõ†áߣàsmÃ0¼EZ¤ìé”e)Vš¦Ó4)¼¥išÒ4«,K=/RÖêûÞ#"®ë²õžž\×cLß÷zCÊb]×<ÏÅʲlžg}0Ïs–ebåy¾®«‚”ýWÓ4÷‹gÇ©ëZàWÕuí8ÎýÚØ¦i¤ì-ËrÏÆq<Ž£¾ŒãÇñq»,‹âë”E×užç‰UUÕ¾ïú°ï{UUbyž×uâ›)‹mÛŽqcß÷Û¶Õ'€¶m}ß?fŠ·mSü4eq¹\¢(+I’Û£Àsê#I±¢(¢>HÙÌ^cÄ*Š‚}cÝ(.ŠB,c W„’²عCÜ(ãcÐOrÎÁ,e1 CQ®ëŠSÇÆ˜yž-€·7ϳ1&Žcqr]·(Ša,>>eÑu]š¦ŽãˆS†Zëq-€73Ž£Ö: Cqr'MÓ®ë,HÙßæ8޶m³,{Ýi=ÏSJÕu½®«ðŸ¬ëZ×µRÊó¼× 6˲¶mã° eÑ÷}Y–_ÿi¿I)óŸO‹_à;w"!…q|ÀŽE0N› í`˜üºìMÌF«&±7íðŠØÄjÁh›(ÞÄ[vñÜÁ}¿:0ùÿ•Ÿ¦µ6m2ÛĶ”R|c‚\)eâÜ$ú ˜²ð¾q˲ŒãØqñÈó<"2¯Ã0lÛvÀ¶m†¡,K"òiš–eÙ¶í ²ÍŸø|>¯×ë~¿ßn·ëõz8‚_ìÝDkQÇñ#² ˜)cƒ*w °M!Ãå†iV0\Fw·Xæ*Œ1Ý  b0ذÁ¡µ[5Ɔš±™îyA\¯/Uï÷p¾Ž¿ó›Íæv»yž___F£‰D"•J©ªZ(J¥RµZ¥”6f³Ùn·»Ýn¯×‡“É„}0€Éd2{½^·Ûm·ÛÍf³ÑhPJ«Õj©T* ªªÊ²œH$¢ÑèÚÚÏón·Ûf³‘wLMM-..nllìíퟟ¿ìÆà=ˆm€ÇÇÇ‹‹ EQDQôz½|¯^XXà8NI’2™ÌÕÕ•®ë£Ñˆü8£ÑH×õËËËL&#I’ ÇÍÏÏ“7,‹×ëÝÜÜTåeýÓÓûŸbêõúÉÉÉÖÖ–Çã!o8Îp8,IR.—£”ŽÇcœÀx<¦”ær9I’Âá°Ëå"ox<žX,vzzzssñ ?Þóós±XL&“Á`pvvö·‰¿ßÇUU-—Ëý~ŸÀ_è÷ûårYUÕx<Îóüôô41™›› …BÉd²X,†Á± ?ÆõõõÑÑQ0´X,ÄÄápD"‘t:]©Tpíþ Ã0*•J:ŽD"‡ƒ˜ÌÌÌ„B¡ãããz½Î¾)@lcûìì,‹9Nbâóùvvvòù|«ÕbðÁZ­V>ŸßÝÝõù|ÄÄårmookš†oÄ6|÷÷÷Ç»Ý.Šb6›ít: >I§ÓÉf³¢(Úívbâ÷û ¶áK¹½½M¥R+++Ä$Ȳ\«Õ|1µZM–å@ @LVWWE¹»»c€Ø†Ïý {ii‰¼²Z­‚ hš6 |yƒÁ@Ó4A¬V+yµ¼¼,˲®ÿbï4S ÃŽ?Ú¤@`+ÙØ JÛ „ D… ¾+(‘ô-ß-ljí«`c£+è΀Ø(óÞãË8Žsf[Çêÿ»‹¿÷}žç‡‚ØÆÚÌf3ÇqR©”øB¡P±Xô<ïõõU|ÏãAžç‹ÅP($¾T*å8Îl6SÛø:···…BA|áp¸\.‡C°A†Ãa¹\‡Ãâ+ www bŸèéé©V«ˆÏ²¬^¯§6Z¯×³,K|‡‡‡µZUjÄ6>êòò2—ˉ/™LÖëu®vÛv?¬^¯'“Iñår¹««+±wY.—Ífsõ”J¥ÒÃÃØb÷÷÷¥R)¬º›Íær¹TÛÅ/Û¶ƒÁ GGG®ë. c±X¸®{||,F0´mûññQAlãwãñ8ŸÏ¿ý2þ`4½;ÍçóãñXAlã—n·{zz*¾³³³Éd¢ð&“Éùù¹øNNNºÝ®‚ØÞf×××étZŒh4Z­V§Ó©¾L§ÓjµFÅH§Ó0"¶·Q¿ßÏd2b$ ×u>ÌuÝD"!F&“é÷ûŠmˆmxž—ÍfňÇãNGàSu:x<.F6›½¹¹Qljlc0¬f³c±ØÅÅ…À—q'‹­f¹ƒnb›–e‰±¿¿ßn·u- Ýnïíí‰aYÖ&ìc&¶ñòòR©TĈD"­VK×Z­V$£R©×ÿæó¹mÛbììì4ŸìÜ1 Å a\`‘ ¡€ L´*Ð `"ˆ XyEÀÿ†j É}.n9ùb÷}cÔBè½Ë ÷BP“1æº.±½¾ÖÚ¾ïjòÞ眓söÞ«iÛ¶Öš€Ø^ÖyžjÒZ§”–RÒZ«é8±½šRеö Œ1–7Æx§ÎÖÚRŠ€Ø^Áó<1F59çj­ŸRkuΩ)Æøû³w‡ ÎP†Om[0ÙÁnG0 Ãdïm‹"v«­Èí`Þ‚Ñn°;Ûùá„õÿÞm—Í÷éÞò}ó¬ ¶ÿÐápðŠóùüþþž?‰mæy>q8ü7ø€iš‡CDÇyž3bûÃ8Žûý>"N§Ó²,ù‡X–åt:EÄ~¿Ç1_9±ýòòòy³~Û¶üOضíáá!Šççg±}½º®‹¢išüßhš&Š®ëÄö5z||Œ"¥” )¥+yÛUUE1 CàW ÃEUUbûZüaïq%„¡0 ÿ‹Å¢È c ¨Z,kÅb±X©ªmŸ` Ûiη‹“{{; ƒ¤$IÆq €Ç1IIÃ0Û‘óÞ÷}/)MÓišÂǦiJÓTRß÷Þ{b;NÎ9cŒ¤,Ëæy˜ç9Ë2IÆç±›ëºÚ¶•”çù²,ðˆeYò<—Ô4ÍyžÄv<ö}¯ªJÒëõZ×5´®kY–’ªªÚ¶ØŽÁ¶mEQHªëú8ŽxÜqu]K*Šbßwbû·çyÏ´»®³ÖÀ?±Öv]wÏ·¯ë"¶ø"ZÓ4÷L›Òþèí÷û-©mÛ¸ï¥)â_¾îÛãeY²=ß³O~¿ß6Æü±wžÉüqÇ?Á!pŒFp`œá A€afA"3  Ãl€æ„(ŠDb°ßß×Ez<žŸç­êýú#ÊÛ羟ÏþÝ#¶×÷´-Ë:æh‹Å" ÃN§ãy^>Ÿ·m;N›¦iF"‘¿H$†a˜¦™N§mÛÎçóžçu:0 ‹…ú`6›Y–µ¾¿Mlï“B¡°¾§=Õ‘™Ïç¾ï‹E˲ä[,Ë*‹¾ïÏçsõÀx<^ßß. Äö~(•J"rrròöö¦ŽÆd2i4¶mË–d2é8N¹\n6›A ‡Ãétº\.£(ú§¯5úg3Š¢år9N‡ÃaÍf³\.;Ž“L&e‹mÛFc2™¨ÿt²épqÄö®»½½]Gæëë«:¾ïg³ÙíÀv]·ÝnF#ø£Ñ¨Ýn»®»ÞÙlÖ÷}õg@‡ÛúßÓóÝZ“œU—Q•â¹à:c?U|0¬àÀ™¼]'²·±l5­ÞŸ¹lwÆÂíioÊ‘ÿ 1­–’Ÿp&w×…‚ý‘E¡íGã§’=çõe‘ÆÊKubN]ZACfI³¥²ÓÑv¥þê·=~¨ˆˆñ;³IR BÑÐÍÛÒ²Ùž}}}ßþö·¬\¹RiÎòå˼ð ýýýJ+úúû®ß½Ò~µ±ºË%U²¹:!É}6¼0ø¨uÓâ­©¯MûØgXrܶ9¢($Ù}Î\(²ªË)øúÝËû)"ícüÎt’$54¡ˆˆˆÈkÅŠ¤=”&‘Íö˜7o€þð‡JsÌf3¼rrrÔìôðñƒŽkM®Ö\C…NWrøTÎö ãŠñ åú·‚²Vµm9—¿?¢øP´ýXŒãT¼ël¢',¥,J_qÑPo¬N6×êmõ†ÜSA“­¨%×ÞVèê°—vº*ºËd”vºå?å·äÉOÈm4Ùê3-µú¬êCUBzELjYt’'<Þ}.ÖyZg?Y|øLÞÞ#ÖMûËebmüO(sn2Û&Ss2YWÚ^Ø}½­¯ÿ±Ò"ÆïÌ'©^’,yIc@šD6ÛÒétð²ÛíZ]@¾nÝ:5{\»s©¶Ç“S§sž8jÝ8æÔSæÒC– §óvK•,³TÏ–ÚôÂælw‡³²§bÚ‡úRâKq¯¯ˆ‰w‹(>|:oÏaËùØÛÒ^õ+’™4Yà*+fk{Jå!¨ÉGÄøeüJ‚àbr""¢ÁJJJà%­"›íç×ÕÕõÙÏ~À”æøÆ7¾1³'¾îËâLgkNFyôù‚}{ ‹GV±¡æµç ‚=²jRòÍŽöb©†gõp¶—ä7Ye’MæëÎæï 6­ùUË£8Ÿ¿/½,ÒÞbk½Rïá5 ˆ¿Œ_I$e("""ò’öÀg>óiÙl?§ÿþ÷¿þñ(͹~ýúÇ?þqqqq3ð¤ênwzyÔë†ÑŠÔ%'r¶ËÂÎŒÊ8©h+ºË¥ºÕü(ï*Ík´Èüž,š=‘½]ÂÈ's̶ÙPqQæÍdi®"bü2~'ˆ¤ ’2$q("""ò’&€4Œl¶ŸGXX€~ô£mmmJsÖ¬Yà/ù‹š1:®6ÉâR9xpº-íƒæu ƒ“ßÿØ—É‹¸t«K1~¿ÏrU¤¤EDDD¤a„—´l¶ŸÊ /¼`óæÍJ‹Îœ9à'?ù‰šB•v¹uÖ_,Ê¥>1ÎSr±íÔV®\§š)—tß’¼”Ê.‡"bü2~Ÿ‚$’D ¶€´l¶Ÿv‰õK/½¤4ê—¿ü%€Ó§O«Éwåv¯µ&)x`1¤Ü@V*[Y7OïÍ´áE¡rx•d˜VÙjSxw71~¿ã“Ä@’ˆ"""¢A¤y°iÓ&6Ûãq¹\ð2J‹ªªª|ðƒ|ðàšLÕÝ.]Éÿ ŒœHœ\!{gRÍÊ­¡.y)òjü¯)Æ~Œ;º‰ñËø‹$I$•(""" Í#¼¤d³=¦ßýîwæÍ›§4jÛ¶mæÎ«&MI³õ y­¿þ»Pd«3Ìäš•ÃZ—q¾ ÈÿÊ[66f)ÒÆ/ã7p’>H*QDDD4ˆ´~ÿûß³Ù]dd$€Ï}îs·nÝRõ½ï}@JJŠšíWü·ì†˜Ö$zÂ\öYT³òâß÷…à¬U¾7x.oë•zEÂøeüNÒI%Šˆˆˆ‘RIQQQl¶Gñµ¯} À‘#G”Fµ¶¶úÖ÷÷÷« õ¨ïafeÌÿ/†5.7TÆÏÞš•C®òß9$7<=î{¤H¿ŒßÀIúð­$—„¢ˆˆˆhi$HSÉf{¸Ý»wkþ»õr„ìd\¯]Ö^20¢³/ï.›íÕ*GEO¹Î~Â÷NCMk*:Kiã—ñ8I"<“œˆˆhœuÄÒZ²Ù~GOO|«Þ¿¾Z«æÌ™ 44TM·ov^8Eéxö¶ÜF“– VŽÜÓ1ÛVßûsž¼ÊãÊ5€ñËø ˜$’P¶ßêCúPoo/›í!ÛÙÿýï+Mûò—¿ Àétª‰]—æ+ãve,H-‹ÖjÁÊ‘\¹Cÿ–¼èú7 Š4€ñËø €$’P Må;Gn³Ù¶Ûíðòx|èêOêheãW áBÅ·rPì? ¢ß_dí)‘dÏ ±HlÀ»±ä”TXXèQlwîÜYRnn®ó†¿ýío’ž={úƒyí.à<Å]¼§Ð£lÛ_ úýEöמIö¬ÛˆÄ6¼KNI–Ÿ¾Äöüùó%µiÓÆù„žãB1eí»ÉVñ{P_W®²Á˜²f„‹ýþ"ûþM!¶‰m°ð”dêElŸ­ŸŸOl ÁøÜzzç)¾è¶Ó›l0l<\ìö7„ì/±HlGXxŸ¹üØ®­­•Ô´iS÷ÁÛv™ޝâ<ÅMX̆‹#Àþ†ý%¶‰íèËOI–¢ íÞ½{Kêß¿¿«'Ävå¾RÎS|Ñêý1Žm`CÈþÛˆÄvô€å§$KÑ$Çöôœ³gϺzBlnÄyŠ/Z²mZŒcØß²¿Ä6"±=`ù©çX&6¶ùåI_|ñ…«?Äöäµ£8OñE§¬ïØö7„ì/±HlG|þùç’,H“Û·nÝúßÿþ'ióæÍ®þÛæê#ÕÁ•†hÃP7.¦ûBö—ØF$¶£,B%YZ–&0¶ÓÒÒ$õìÙÓ……Øž¶>#8ÔmâÛÀþ†’ý%¶‰íèKQI–¥ ŒíöíÛK*//w¡ ¶Ó+·/?¸„;m ‚‘ˆolû^ö—ØF$¶£,E%µk×.i±=wî\I;vta!¶+vζOZ3bÏùÝ\«>k`cŒD¬cØßð²¿Ä6"±=СCIsæÌITl¿dŸŸŸïÂBlÛ•6u]šýÏÄ5ÃwœÝÊÍê§öC?qõpûb¬cØßð²¿Ä6"±=`A*Éâ49±}øðaIÿûßoܸá±]w¯[9hË©—«oÚúØ•ƒê.õ¸Ç6°¿áe‰mDb;zÀ‚Ô²T’%jBb{À€’>úè#×`ˆíº{=oy¿Ô‰5ܯþ˜:±:oyߺK=Ö± ìo²¿Ä6"±=`Y*É5!±üÕh•••. ˆíº{=½ò÷Å{ ¸b}ð/öÎ::ªkûãçIå¹ÔžK}Qwƒ R%U¤wá.Ó."q|ÎoNØ–wbJ–J'£ã9» ])çÁÐÅz?-ûÃ6a›ã—ã—°M£¶)ŠjONÕWm ÛË–-C¼¼¼Úæö„m?Ù¼0Ó_ª­)pdìßiß •†îC'Jo¢[ѹRNض©8~9~MFئÑÛí.Š¢€¨J)àªaûÞ{ïE¶mÛÖ¦O!lê—降Zœ5I*¯Ú=7­1Î^A* ]†Ž“DW¢CÑ­('lÛZ¿¿„mÂ6°MQ”ÕDUJWí ÛMMMhÀï~÷;öåy€m±Ú“U µ–åL•KpÒÌΚhž0dqC¡›äX ºˆ®”_ ÛvÇ/Ç/a›°M#lSeAT•Rû÷ï·%lÃû²#Ïl‹5œªÃÜŹ3p•XxahZc|ÝÉjëD¨4t:]£» ]†ŽC÷I¶}ÅñËñKØ&lÓÛEQU¥TPP-aû€÷»víbGžgØÖ–Õ”Y´È‘2ò»„›ÊÂvHoß •†.@G ;¤_ÐAè&t–®@ض¯8~9~ Û„m»ÛœàcügÄÄgµîòä¼\>iV0aÛâ¢(  ª”ºÿþûíÛ---pý7¿ù {±a[ÏrÄêAc¢leÞ¬­krš“j™+;y°šÜæ”­•kñò©0tž'LØ&lsürü¶içÓê¿¿&6VÙò]xý”Rã&ÌjÝ=­ŠÅåW\y5aÛú¢( ¸ª”jnn¶l‡††Âïþýû³ Û¶µå4'G/ L£ƒÅ ´±ëö"^ÜûFN[D¨´¢7w'ÖmÄ\Ó ´qúµ£ Ðè]°MØæøåø%lÓοeíSgŸVLئ(ê"pU)b3Ø~衇à÷Ž;Ø…Öm±Š£Å) [,.Êœ wÖ“T£Š¥6l“#a[m´ªãe™ûwn(]¾(k¢~½²A1NÜMi؆.š„mÂ6Ç/Ç/a›FØ&lSÕ^®*¥€®v‚íƒÂé_ýêW_}õ»Ðj°m´‚ƒYH‹­ÝhH—ɆºÓ¶T¼ž×’úƒîÆ•œÛ*×®Èi|“A©c‘K¨ÛPx(×X™°MØæøåø%l[Ùj½›W~pßñÏÕ +Zþ¿ùÔç­Ÿïýæ{Ç>:W>cö8üñ¶›N|Zºï´û¢i-§¿ lSe;W­J©Ø¶.\½½½Ù‡mm §ër[R ël´-ÏŽ4³A0Z}¢BêÓð*ðBðZðrðŠL/mÕî9ñÕù2ðbW¶ Û¿¿„m+[ÓÉÏ&Ïù×u7ªïtÛ÷· {ä±®7u¸­Û³/:_ûT÷—ñÓ˽âó´¹ ñyäø)åMÿÛÓ{ÈŸþü7…$įƒËwf•ŸÕ»òpù?Ðõ<Ÿµ3 Ãb~¨Ï°×­ÁMú [X{¬ó“ÝQDVüýŸ×Ê%ø€ )ùuFØß’úŒW¸-ðüB¾zi·6øóhç§Q†;/ G a›¢( Ъ”ÀÚ¶;vìãââØy6ms*³(ëY”[áe¢HeìÛYrxÏÅ£±h2Žæã%8¿Ì2ÝX¶2»)±æD¥›û¶ Û¿¿„mkZÍïtzâIåJ#ÆM–:ÞƒFIINi‹ñÚì’f)Ÿ:g¾é‡Ï`M³Z€ÒÔ‚z÷ž¬ŽÞ)•ïú¬rÒ’×7zϤ9(¹ûþ‡5·ƒ¨}‹K-Ò°-ÿA`Ò÷<€¬¸Ü©ìQ¾Ó”“€Ù„mŠ¢l$@«R kØ~ûí·Õ}øá‡ì<;¶Ѫ—ï>–P‹ÅŠØzב<Ò¡:RF!™[² ÛåÌ,;RXªÆîq9š€† 9hš†¢™¦†ãUà…àµàåàáEï@ئ8~9~mÛ„íñgË‹>vR~Õ›˜¶ÉÕT)ܰ3u¶&È]¯0#PÊ‘:Ö°-z±g¿´= ˜° ú•’Þý‡{Û’¦ÆCwWZ°2Zg¡=÷ÙÛ¢[n»+`šcUävÜsÝÆ$)\ºf<ÄåÛúÿ©ÞSsþ#Å-…Ë×o59‰ú‘[Óñ¿+· i¶)в‘­êŒÞzë-À¶üß@—.]Øsö‡m— ¢‚Œ};Î$ˆ‚ä¤Yg N¿,gêÚ‚×ËÆU­O®ßœÝœ„EØyÈRÛ Á%8÷à$\…Ãpλl‹&£áh>^‚ó ÛÇ/ǯ}a›° H–·Ú«ß0ÓZkÀ­0ª¤sñUX×Ñ€ŠD´|Õ° Ê5VÃUr+aûÁŽO`&¹.׸¯<÷ÙÛ`f,êödƒ4hKb1…®æòps!¬'×ղЛÛEÙN@W™—mØ1b| f·Ù¶=0L¹Ì?˜!$,tÄÉÎI$ç¨7,o¶ÚT¶½:rgM .O®ß’Ú‡88«)gê`9%6Ú{(·øÍ|c[~´±5žUwª¦ñt= ð…ø P •q .Äå¸ n…ⶸ9áqx(íÌÎé>4Í‘Œè~f)a›âøåø%lÛ¶17[ÞjúÞÓO†—ŸSý§Î—¯È KL —’°ˆxl ˆjêi#ˆ6ý³²ˆ5Âö¦„ÿzcÈ*KynÙÏ}6Â6ÒÔîFŽô¸éžð=ú ÆçŒÂF¹0hézS5¬Z'lÛKE]•RÀXÀöµ×^ _+**Ømö‡íÖO^Åù´šqFQ|Uxlér¬“\ž3=$Ý ±ˆÁ¸Çàœ„«pnË„R»˜´EYXÇ/Ç/aÛ°}ȾC–GÈ šâ+@W¾Î \¦óÆ2éð¬a[Ï÷vžm®Ÿâ¼.Z’ɶ÷ÖÕ×'±#ì¹Ïâ¡®é!l TíÞ;ʬx|ßœ"b†¹©Úœ•„m{‰¢( «R kuØnll„£þóŸÙgV„m Xéºò£EHaa'lŒùŸ[+Öl._µ¡t&‚â àˆÂPÌö\SàX?weÞ,l¼4{ ¼ÅžF¯SÇ"mÃ|E!~BTCe\‚ q9n‚[ᆸ-nŽGàAxŠGøáÆIÂöÅ&Â6Ç/a›°ýR¯ΓÃÅ¢ã2å…ƒu5vêܯNùá+_5lc;± Û›ó5lKbÜ l{î3`[6ló¶ÇøÏpÛsCÂäŠæÿ3U[Gض(ŠÀ*¥, ÛË–-ƒ—ýû÷g‡¶iœFNqüÚÅÛ„í>GÊ^_¦r9ÇË4o\ç‘yNÈ®”Ï»²+L° wÛ«£và ,£É‰Ö¶1±Ü l{îs+`G¹m¼—óÒa‹×¶m'Š¢°J©¥K—Z¶»wï/cbbØa„m»a›"lÓÛ„mM§˜ î|€¶ü¤÷*«:ð–” Á;Ògª‘x=‡m7æ!l{ès[À6¦»Ë…¦½aذm;Q€UJ=÷ÜsÖ…í¯¿þúòË/‡—'Ožd‡¶íb„mаM#l¶õ"d¤—å€U,Æ–Áå/ôè+8-SÁ±~ûüö‡>·l—4ž’ ½^îc¬ƒyïx4aÛv¢( «”ºì²Ë¾úê+‹Âvvv6\¼çž{Ø[„ma›"lÓÛ„í¦“ŸÝÔá6Ùçl{z‰6Ÿúû„ÉÛŽÝ‘c¬“¥•AÅ 'Ï?l{â³{ØÆÑÜRsNð ÏaÛ¸³:4;h¹”Ôù@Žã&lÛQEc•R@Z‹Â¶Ãá€~~~ì*Â6°í^„m°m5Ã9[žqˆô#uÄ:çouö<)¿v{öE”œØöÄg÷°mܤ bý¹ç°ååú à²èòhf¶m*Š¢|}}•R@Z‹Â¶,ØÞ²e »Š°M#l»a›F#l[аəl-nÔÄ™ArüµÉFŒ›,ÖÄ&˜~2:À%lOšì ˆâ†rgäŠåq©ERž]Òì±Ïú`3×[©a¼¾ ÷G‰dËÇOœmªùÀáÇhë’ÂÚch£2è¹{oØ™Kض£(ŠÆÊ²m‹Âö•W^ ÿ>Ì®"lÛÎÛa›FØ&lKÊgG/[»yÁÊhp,rË¼ÏØï —TÖ|î¹aÖzFa#¯Û˜dšKOض—(ŠÆ*¥®¸â +Âö¾}ûàÜ?þñöa›FØv#Â6FئÑ,ÛEQ€Y¥Tcc£å`;""žõêÕ‹Dض—¶)Â6°Mئ¶)Š¢³J©ððpËÁöðáÃáÙ’%KØI„m{a›"lÓÛ„ma›¢( 0«”6l˜å`û¶ÛnƒgÅÅÅì$¶½Œ°M¶i„mÂ6°MQ˜UJl­Ûo¿ý6ܺä’K¾þúkvaÛ^FئÛ4Â6a›Fئ(ŠÌi•Ro½õ–…`;==>uêÔ‰=Dض£¶)Â6°Mئ¶)Š¢:v쨔JKK³l‡††Â'vaÛŽFئÛ4Â6a›Fئ(ŠÒ*¥€·‚íÀ§uëÖ±{ÛnlWÞÎQþ#fÈט„h|:ÛöM#lS¿ö7Â6a›Fئ(ŠÒ*¥ú÷ïo!ؾûî»áSQQ»‡°íÆBW…(¥þxåå«ÿ ?|íp[Û7°MqüÚßÛ„ma›¢( H«”ÞZ¶/»ì2øôÞ{ï±{Û Ö Ûǯ°Mئ¶)Š¢€´J©K/½Ô*°½ÿ~8tíµ×²oÛ Ö Ûǯ}°Mئ¶)Š¢þýï+¥¹–€íøøxxãååÅŽ±lW*Ï,Ϭ=^ó#ïÓpª~wm^iKÉY«5žnð$X¯?Q—[Óp²¾Π99UÙÕG«ÎZ³ì`©'7¬:\YÒRܺ7SùfÚrÖj¨³wß^¼Âö)Ž_Ž_Âö§Ÿ~ZQQáçç×¹sg¶-Œ°MQ°UJÅÅÅY¶çÌ™o¦M›ÆŽ±2l#ž0{¿®û—úN·ÞykD|¸®ððcÝØáÆ®Ïvq¾¶[÷nøéÅÞ/Ê×Ä‚„ÎOwÖ÷AðÝ£_ç 8$,¤SçN¿úõ¯`?ùøkË(q¬§—¤¡¦¾áHÈßåa»Öl~wÐ×¢h&ÁT-zg”8#<ßÓ+61ÆXaÞ¢¹h£÷o¼Eµën¼Îów˪ÈôêÑýš?_ƒk¥ÉË_3^—‡Kàmͱê!c‹Ã{÷¶/ qürü¶=š’’Ô§OŸ[n¹Eý·Û4Â6EQ¶ÐÔ©S•R€\KÀv=àÍÆÙ1–…íò7ÊyâåJCÇ •:¯ê-%¥éÆkIKù¤9ñ5iO¢r¥¿ýóoEM…r ²=#|‡+'!JvÖ%´UNZ½qõYÛ¼2X¹’)¼?e¼r¥ùKæë:ã&EÉ]÷ß…x$X÷ðÀà­ËVôìß³îx­Ô‰Ú)…r[¶­ÅñËñKØF⺼¼‰k___$®¯¼òJå¤[o½à 'lÓÛEÙB[¥Ô+¯¼b ؾùæ›áMmm-;Ʋ°=fâ%¡ùØ!˜®‰ÌÌ–´ÍL¥Y#ÔÙ”¼Q¾Nž;I®2…ÔHáëc]•€{Cb,¦}bR«ä» $—ä’•Ñ+t¼»~ë:DºK×H¤î2X‡ŒR”’W“7oñ<)AŠ©êˆ»i¥‚¥&òW8”©?ÌêD¥0yo’NéjñÙq¨ƒö"+(…’ÔÁ:$É:ßi¾Ë#—{øN êó5±¬Ý²@ I3)ÄË7ëò†û GcÑ„mÂ6Ç/ǯ-`‰ëääd$®_}õUçÄ5tÕUWuéÒ“Æ###1ü³Ï>ãšma›¢(Û `«”äZ¶úÓŸÂù7Õ‚"l# ”§c²¨±k\Jl*é,ùŠ@ÖX 7 £ËWÉÿ ?ÌXw–é£rÜP"W¬~ÔuÒŠS¿/X0Êx7ÌÞtÎ\9ۮݻ¤ÂqãSi¢m èeæí÷ÜhÞØv™/úÜËÏ™‚õ§¼ž’±ž¿“Þ{I~¯Úè ¦ªJ{e ¨ÖqÏ= Ü °ÍñËñkeØþä“O~üøErô°MQõðÃ+¥€ºí Û±±±ðÿ³K, Û/ôzÁy"¥XxÜzq ‹¥äžï‘}†ä«LÂ0¢¿qv%’EΛ aöf~ÝnT˜2KJŠ›‹L[¾Ô9Xב·s ±¸ìŠü}Á:.¾Ä.w’™Ÿ~Ó}ÕÙ„¬šÁ1gÕè†'ïY/u6am§1XÇT¶}ÅñËñkSØ–Äu`` ×:tp™¸îÚµ+×QQQH\þùçç9Û4Â6EQv÷TJuÛ¶çÏŸoñs¿Û’Ÿq™€Â¾AzŽ¥)W†½ŽôNìKdºI!úØ"Èxl>cN¦á¹¦«³:ëX{iª¦·qzúù§ñ§ #^7m¬ *@ [Ë2N²dø é,ùŠgaëc—†9«îƒu÷ïD—`ùè÷=3f Û€8~9~mÛüqYY×>>>H\_qÅ.×}ûöEâ:--Íeâš°}qa›¢( x«”r8í ÛC‡…kÖ¬a—X¶uDŽÛù°YùIòH°Ò¥R‚bqS”#ˆ›îÌÝaÚÀ ©*¹ “6±Ë±i£`mØjØåšOãÄQYä‰:.WQšž g$ÖßôªTãœXDÌøj ñq9¶AÆg÷Áºûw¢}¹ÏKøjZ¼ŠGÀd[f¶ÝÅñËñkeØFâ:)) ‰ëÞ½{»L\_sÍ5H\ q]UUõ}‰kÂ6°MQ¼UJuÛ¶ñ/7üHOOg—X¶uÀŠœ’±:f“:OõêÑ]f]J¢I¯u„EïŠ6®Õ¦ØÙ–±ÏêL‘±v6Æã\ëA+‚Œ5±nSoSìÉZV½Ï“é¶(GVMÏ’5]Ž¥» Ö=x'0)Dë€Æò)ó§O"lÛ]¿¿Vƒíõë×#qýøã»L\ß~ûíH\‡††"q}âÄ ïLئ¶)Š¢€·J) n;Ãö 7Ü?šššÚ®©„í~ÈªŽ—·.žC‰Í‡$šÜš¾E/ÝD&G¼Bé2VvŽ,±ÆR ±ŽTçÙpÿA£s\ÞC¼å댠éz‡a„ËnÎéÅÙ¹é&äïB=©ÕM»p"®\;;t¶.,;XŠÚ¸DSŸ—»*6L;0+@ §Ì›ì>XwÿNLóTGO­É¤!p"ÛDµE°Ž? üaàσãËZjûñËñËñë2qÝ­[7$®£££‘¸þâ‹/ZwgÂ6°MQ¼UJuÛ¶/¹äøµam×TÂvDa0b²‚ƒ™­Žêb¢+3±ï.âHçü•ΘI¸ u}¶‹éWœÐ+?!„5™ŸîŒ[éPUê`sc}|@æMê¸ÌŒiáWã¢Mø|VÑ»ƒFÀ8CH_®×…Ôçk1}û$kß°sëI°îæùèG£éFa¥hëø“Àþ<8¾¬¥¶¿¿¿âL¿~ý¸Æÿ¾ŸÃÄ5a›Fئ(ŠÞ*¥.½ôÒö„íÓ§OËÿ¦·iS Û 5‘ˆÉR¶ý˜ÀÉ6¼FÌôw™}ÂnÀ¦l’6ä¾$fÒ¨€Q8­×¸ S2TZϾø Ò_Æ`é)‰}§:¦êxZ*À[O•[#[1iÉ妃p¯›ªáqgOD[L“ZõbNÏ߉ŽÖ£…=Ÿðœ'ñÊIK?Þð'? üyp|YYîÇ/Ç/ǯuÎÙÖ"lÓÛEQ€\¥€·Ý`»±±`#–6m'a»ôPb²5ŽÛ!½ƒ³s­]„݆ K¨Ú:C”Œ™™óÍÅÅÈA!F¡s¾§ò`¡éê«%ä>Í—‡³…°a’ðƒç–X€zfð < Û;aq©ËjرÕK˜ ZÒRŒ’snEM…‘Û#ðNVD-Ï,ÏDI›þ$ð‡ñ-{ç[[ñYDµQ£F6lc'±“µƒ5ƒÕ³mÛö{ųmÛ6;ÉY3º÷ûßs¿Lì3ß$3—>ò•*ä÷ÿE~Û 1¶Ÿ„ƒpB~ òËØF(~ltêÔI’oØØ9r¤¤×_3 ]Œn?¸Ñeñ‡.gsvާ§"ŸÁ'áà \_T€ü2¶ŠÛ¹’¼8»ŸÉŠ…ü¢ä—±PüØðÈ•äÁ6¶?ÿüsI]ºtÁŒâ£Uf»¢õ\öIÛ±UåÙS‘­÷ø | Ä*œÂç‘_Æ6BŒm k×®’}3R(Fg®·¾ç/o§¬üjÎÎñ%ôÛKÈfÙ2—9h+m(ÁÉä—ü2¶ÓÀ#W’oØØ®®®–téÒ%ÌH§m>±¦ÿª¯Ýö2ÛЧùðÒ”K*²Aã6ôþÍ2Ûg‰L^!¿ä—±>¹’ªªªÂÆvee¥¤7n`FjÅèÀ…íS7úCÿûfÞ®‰;ÏmK§¡"ÛaSlÍo6Ù2GX€ü’_Æ6@,¹’ØQßRò“LÿŒ›„•¼YR¿’}¯m±££J—Ãøcâ—ø¥Ø ‚£Ø&1êɵ¨'ÍqφWé£n{íK/GÛ:ë2ã)’ìï¹I@É(1%é› Ÿðn´µ—÷æZ â—ø¥Øþ<Û·ZÝ~x=5ì¯JžÚm]øfZyÔ³¡2uÖ×g'óþò›ä’hGß.v[U'O¥G·Þ0ˆ_â—bûë Ø†ü×jôf¿¯§éU§ßÿ×dš®åvÕH-d]ݦähŒ¤üß›¤põ˜j3%Ž$’Poê&%æØÍC¿Ä/Å6Å6“=‰ÑãgÔÀÆÔZ|ĽFyç;·–'|›KãÇÍí•ÁwÛdk!¤ærSÎÊe9.÷%ÂûÊH.‰Ö9™~òì‘@ü¿Ì)?ŠmÈW­ž<{¸k§eþûIêçÊó¡½5™ ö®ú@¿31Í÷Ô\.ȹ#§äš|ßkIq>´ËÜZ’öI¢§Ï?â—øeþ Ø†ÐêÖƒk]ÙŒ¯§±2qâ¨{­ÒÖÞvYªGÎéÀö+ÑÃUés¦¶rW·)<èM%§B:.3dŒL’a2OFÊT,³?摜­Lžðõ4ug3Áøù¿Ä/ó/Å6¨VÏž?»5 Uš,m¥%±Ã'}›ÕG©í'n[šfj™_-Dt.¸ûrôPIüXyâTUê¬þ­T]všÚÊ-íUöÎ:gw“§×âïs„{)¼ï¨{Ýó<;6ÛNÂσƒM±·º'ÿ’Ô®fï.xÙ£(€¿/»îîî»uww7ÜÁëÅ¡†¤©ë}îë»”ÍùwÎ$ÿæä6ÃöîæÊZraeÒµ:ƒZËœÒ0Ãh&G•þ©§kLlâúÕ]¶²6sa£ñU­îi%û Tu»@~íµôâó‰3t  tµDu›î¢4^µš :­¥½ŽªA®~Tl‘¸;¾>60¬Ÿž0ÏÊí ¬/æ ¯Î¤Ö—v÷v¿/ ù6íŸòào À{ lÃqÌ Ð·¿QÓÞ?ØÏl¬FRs8O-WšÚ-ÅUšGod—žŽŸÌùáìJöq‡µdThV†éCúã}àÌÆÊÞþî7êÛ9hÚ(Û(Û€² ù˜ÀÎÞv4=χ 2oO½¢^ÿ¼HqãýE÷…äl‘òf•öI³© ÃVÞí¨îsÖòMÃbÛ˜»Kâí•ùQõ”D;#3̪ÌóZkÐà[ø¨Ãã½ 7\1®Ò¶ ‘`˜Sigäì”D“ù‡o߸»{Dlšû¹†GM§­¢Ñø¶Ró¨@qãïÿ„43§i9ÖiØîŠX™ðþÁÖȃm„í €² yš@z}y*)ê§%\m•æáÿŽŽåWËÙ Æ×Ôr©ñRûe§Ë‚Nˆr¾¤7ç*êTÑ©œK¼}ƒ|s‡­¢Áø¦‚}@ûÙÄ©ÿüF4 äê 3ÌTÒE!`Íü(Û€² È Žåàz+’šãBz©§»Åüî­ìò¿[h©ún‹¹hXlUNŽçÔΈÚl^¸ˆÝ4¯¡!9ÍÛ›LïŠU·ÿý­)ŠÓ;ÆÝéjC«3›;ëXsò Ê6 lcS|ÿ˜ãéªÔ<ø¯’y¥Vÿ¼ÇQ#õ P#õ&<ÔNøƒ'î2α4ŸïvT×êžSÿN¦ZûXæí¥¹÷ÎÞ6Ö@ÙΔm@VÇDSóúiI«¹à¯òÙÄé2õ½VKñˆØÆN34òýµ|â@Qh¦™±½ÍRRÎÞ!9ó×ÜÚ,E†&šžÇš(Û9€² È*· ³±*„C\}üÚ_»b•öÉߤŸU~|ùÄA7£èç+5ÿ±¯µA®žÒë+XsòÊ6 l£l¼ÇÌ¢Gáë«Õ=ýk-,RÞì°U(£bŒÿ’Ήƒã‘[9Eú¯ÿ3ï™Jº°æ¼_8~û‹Ã¯êàà •J­¯¯~H&“Éf³‡‡œH$èÓ¢lçÊ6 «œƒåµ„Ê?X¤¸þGý{Éœ§½pÓnÑok¡$‹Kñ6ß¼bÎÿ{¡âmˆåµ8ÖœÿIJì{gT啿ý̾:û83ÝV})»cMY=&±‹Þl¿¶¶mÛvŒIkçs4ÚmkШQ F„Ä]dsW$€ì›}“ddQqGÜWð~ÿò‰§Þ~ßËõ øÿê©ïyÏ»ž[Þüî9ç9ro—.]2ÛFqq1ê1¢« uuu3fÌ@aذaNNNF놊»ºº2DªáiÓ¦577›»š-õ½½½­T›2e ꄆ†R¶ !„eP¶ ©i-ƪÑJö°(WXé~,LÝ»æÉqæÉXôÛW³^¥æB‰¹ÇP¶E¡­¨¸‘‘#GÞ¿_Ukkkƒ®«Á¥Ož'íâ™ê’y*®{kwS¶Ïœ9³víZTîJ¶Ñ}=tèP©pðàÁ–––†††¹sçJ‰‡‡‡ª9uêT)tqq©­­mmmÅ^)A¿´ÙžžžØkE¶L³¾²-¨ÛÔmB!¤ÿAÙfSò¸óQrM˜HÚ¶c+’j"é®ý7°l˜Z3 +´ut>¶ÙvíÚÕÔÔTZZªÆWÏ›7OëVf Ë}øðavv6l\¤Ô–:¶Ê¶܃Q¶µ§ÂoŒ'—A_::º”NcÕ.©æëë‹)ÖÈ@.Ó¼aàëׯ¿}û¶î´R¿ªª ›FÙ6N,§lB!ý Ê6›ŠÊ–ÏgÝ¡¡Å{ª.VÒWû{T_ª -Þ+mê•êZÝZd'²­|Rºˆ!¥RŽ”c(™­]º.fŽÍ&Û„B¡l³©¹r«õȳ,h{²ÜsšR’p2rSwg~.íQºïúÝ«}+Û0LÝÈê’’9ILL 61[6÷ïß/Ú pÈí§È¦õ:6&H³]¶1Ï\;£Ûßß????$$Dƒ5kÖÈÄlÙ6lØ››?sæL)3fÌãÇQÿE¯8J0Ï·=Ðd›B!”m6!Yõ ¢a—ÄW† TádÄV|õåÑEhè/.Ìo:Ö‡² áÔ•Cµ h!Ý·vmêéÓ§ïÞ½ž©êÛPç%Ë6Òª©ÞiŒZצ7CeÙ–_ „‚‚mï½ÌWå_|ñ…ܹäQP²M!„Ê6›Š¤êP1m,×<à³ 1JÎå:¾]Z<»>¡od[æf¹ÍXéZ6ÑÅmÌ£†ndô'Këu^ºlCnåT˜°-%ÆdæšÞÜÜ,c`¼®Ztt´ìB¯8ß–¿]]]K5H!Nˆ¿+++)Û„BH¿„²Í¦"$¦ÜO¼+édEtðDbM„´{Ñ™ô>‘mí²[jø·QmaqqñæÍ›'Nœ¨íÄÆTg[ê¼\ÙFö59Òžév™L&Ù•‘‘ñèÑ#eѺjX Lv¹¹¹¡ækV‘§ lB!ýÊ6›Š"_èÖÓGé§ŽÒ?[ÄU~%¾]y¾ ÷e[e W m˜œ3œ1âºì)wïÞÕŽ3_µj•Ô ´¥ÎË•mu‡‡ÖíŠŠŠ’]’ü ÇZ콿|ù²:F’£ší´p¼%Ê6!„ÒÏ l³©I«‚hmKvÎiJ£yΈ(óß®¿\Ù˲ µå...R~ñâEµzÖ´u½™ MœVqÕ ®–cX= ãÌm¯“™™)…W®\QGM:ÕÊ /X°» Ç÷>|ø™ÏtWtttÔNWÝõÒ•­€¨#W¹ìµ.Ûx®®*¨lç8¿½È6!„B(Ûl*B::oIZ³ÊlHÑb0ðaÀGbk’Sç“ÎÞ‘mØ©¬P’’i„f£ÓØXùÆXLS!Ÿñññ趩Ϋ§½½Ñ8=''GMÌ6‚¾n¬à…TmH`ŽìèHêfî}zA¶ !„BÙfSRД ­Ú“åNÃdhcw¦›¬Ö›²M(Û„B¡l¨¦"\X;¡êõ’¡£Õaø`D—¤l¿0”mB!„P¶ÙT„ÌݧÊúÃ1ä FVÃ1|0æl¤l¿0”mB!„P¶ÙT„È„íÒ–"ê%Ce-Eø`àãñªÿÍÁÂW¨¹páB3¡lB!„²=`šŠ"ÿLõ’¡‚³9òÙà¿9Ý„²M!„Ê6›ŠP¶“OFQ/ÚH©¥l÷Ê6!„B(Ûl*BÙ+ÝO½dh#²ÌŸ²Ý#(Û„B¡l³©eû@îfê%Cs7S¶{e›B!”m6¡l#²SIJ |ð‘ l÷Ê6!„B(Ûl*BÙö?¾]D‹ÁÀ‡aÈvHHÈKlݺõðáÃ'OžìèèÐ’’’bñ??¿‚‚‚›7oš­’ õKKK­×|òä *¯_¿~òäÉÞ‚?œëêêú‡lB!„²Í¦"”ímÉÎøoú)=“|$ƒl;ö5« 2$''ǬaÑ¢EÖ 3wÁãLJ*Õ¦Njîš7nLŸ>]jùä“Oø0`sðÈö¨Q£Œ»Ðuìáá!2iÒ$l£ÇÛ8êƒÒ­÷Z¿ÿþûRAؽ{·Åj&L ³fÍÒK¿páô[öÆÅÅÙ»lB!„²Í¦"”måÛ»3ÝJÎÐ<[ Ñweº)Ó¶CÙ¾~ýzgg§õIÎçÏŸ¿téRÏeÛè½n]¶…iÓ¦Iý{÷îévµµµÉ.777Lîàà`6œœ,Õ0ŒÜl‰ÈÈH©€kQ¶mç¤iƒa‡a&„Ê6›Š ÙV¾í“¾¶àlýsðDÁÙlŸô5Ê´íA¶·o߯ääk׮͛7ݹ¢¸°ß’’]eä Cç3öÊu¡²K—.EŸpÏe ÉÔo[d{áÂ…]Éöž={dWSS““““ümÌv†A첫¦¦ÆÜxXyLü¾Ð‡²ÞÒÒBÙf0(Û„ÊöóaSʶø¶äÇ:Z}„: æV¦m'²-::bÄÌ^6&-«®®V5£££u”rcòseû½÷ÞC܃õaäB{{;jvuBôcËäpü——§z¹µuÐu/å˜nÿK ßþö·1Ü}çÎȯnÿ²m¾UÂ`ØIP¶ !”m6t²8R²OÊýó¶¡Ïs{&;´ÑÄÒÖht”Ø›l ³gÏF7/:]\\¤9äÚÕ«Wá½¢ÖYYYèOÆHrˆŸT7nú~»=g=·rd&3&H+Ó€ j›6mRiÕRSSug«ªª’]©Æ Kþ3íØxtKµ•+WÚ¿lOœ8ñïÿþïu¿ƒüüç?_·nÉdÂO”mƒ²M¡l³©ˆ™²­‹”ÚØ).ص9ñã¸Ê¯è¥/Ьh\41Íû”môýû‡‘ý[7Ì»±±Q[Í××W%·.Û¢ˆK€h$Ê…üàPzÛ—þÂÝfêgÌ<—Œ—’ÜÜ\U ¿H!îßþe[þ.//G¦ô>øà7ÞrÅ›o¾éèèxèÐ!-OÙf0(Û„Ê6›ŠP¶¿Î˜¿C*`9(ñ1Æ4¥¬ï…@K><»•í;wîhËÑÉ,ýز)s¹gΜ©;iÒäpww÷ž¬³ òóó-®³=Dƒîtíš54¢´&š+åv+Ûj²´bãÆ"Û2Ò[.äççg6€:²z–-=Û‹5À~¡…˜.®DÎÖçlc(xss3zÑ!ÿÆ¥¶1¦Z ‘>-î±±±JÚïß¿/5q)ܱcG?“mè´ßºu+æ½ãß@}Åÿñcî:F%` >†ýS¶”mB¡lƦ"”mDYKQd¹ÿöc+¥òÎŒõ¦ê0Škÿ 4NZM‰E³¢ÜÎeC¸­ÈvCCƒ\ËeÉ^cZod/ïv‚49ÿܹs­Ë¶âòåËÆ¥¹Ñ¡ýšUãM ª” ›º¹k233e¸;r¤÷—¥¿¬.00?7¼ýöÛ8ÖzŠ5Ê6ƒ²M!”íAÑT„²-q¢µ4æÄaÏÔOä¬U~ˆ+„Ùy ÐL²¬͇FDSÊ^û—m³ÙVéÄ”¬*°,¶ìš?~·e'TËmØ(Û?Hæ3•ÂMeGiÀ¸b6nFºôÕÊÞFÆ/>|ø°?®³UÙ’’’Ö¯_oL±öw÷w’b-11)Ö(ÛŒ/Û„BÙfSʶDÕ… Œ=öNûTDÈÝlª¯h-³Ãd 9Ð(hÕLh24šO* ÙV e!¸®ZEE…ìBýnË6@>s©`£l+?‡HK ’‡É`¹/c}•‰ ˉK 2ŠIIHHˆ±¾êÏW˃õGÙVØžbíÔ©S”mÆ@–mB¡lS¶ e[űÚ¿¼mî >›¼ü«BߌúDŠnßš ævA¡™ÐXªÂ@’mIN.ýÀ€­­¶{÷n¹‡œœœžÈö”)Sl_gËuçÍ›'%Hœn\âKÙæRïÞ½*ÇN.‡¨åÄ·nÝÂÀx9¿†lkimmEе+V ÅÚŸüÉŸS¬mÙ²)Ö¤ÛŸ²Í€²M!”mÊ6¡l«Qʘý«íèöI_Z¼'µ.îDïõu³»<­.!´d/^¾¶+M£ÆùTÙÆr%·*Ç5¾_…Kc³'²¹Är~c6ò, þþþ¸” ²Ø•t°«ÌŒ C[-0¦ ±x˜:ÏþýûÑ• Q¿qãFzzº¨»JÀ>ÀdÛ˜b ¿• ÅÚ»ï¾ÛUеˆˆ¤X£l3šlBe›²M(Û*Rëâ÷øòè"%{LíËþ¾—Ó˜ú* “‘w:#¶"cÅ7˜«×Ž&@C 9Tµ-ÛOžíàÝ +Ec£i‰gê'{³¾€‹†•î¯ N©‹Ã¤ed³«4f¸%Ün7‰[Å ã¶qó ‹Gƃãññzá)Û„²mÁ lBe›ME(Û½2Ù$=À˜¨Œ çÆN`£µú¦¯EÚ°¯ }#Êü¢Êpx|eÈÑê0xì±Ú¬‰…éÐHÞ–Ó”vüt&–¡.j>7Ƶ*.”W_¬Dàl¢»PÕP‡à@Ž“àT8!N‹“ã¸.‡‹âÒÆßŒÝõx<γû¤ÞNÙ&”m{e›B(Û”mBÙî«ÁçX_Ò‹5ÆÂKxaž³WêêM‰Kñ v¸Ün ·‡›Ä­â†qÛV„S¶ e›²Í lBe›²M(ÛöU*ŠšóÐlHåñÛ¡Å{‚‹v.ðÆ@n,ô}0w3FkïÉrß•¹Þ'}-}ïHqÁ‚ÕÈI=þòèGèvFàl¢»PÕP‡à@Ž“àT8!N‹“ã¸.‡‹âÒ¸܆¿(Ê6¡l3”mBˆ P¶ ß¡l3(Û„²MÙfP¶ûBe›MEe›AÙ&”mƒ²MyP¶ÙT„P¶”mBÙf0(Û„—e›MEe›AÙ&”mƒ²MyP¶ÙT„P¶”mBÙf0(Û„—e›MEe›AÙ&”mƒ²MyP¶ÙT„P¶”mBÙf0(Û„— e›MEe›AÙ&”mƒ²Mém(Ûl*BÙf0(ÛOž<9þü¥K—l©ÜÞÞ~÷î]ʶÊ6#`¯Û÷¥™¦}|”mBe›ME(Û Æ –íºººI“& 2DžbèСK—.½yó¦¶ÎüùóGPPP0räHT[¶leÛe›1ò?‡ãÓ²òãø*(Û„Ê6›ŠP¶ŒÁ+ÛÑÑѯ宯¯WÕÆŽ‹ÂÙ³gË^Ê6e›AÙ¦lB(Ûl*B(Û Ê¶e®^½*ÚP묬¬{÷îa$ùÎ;QƇ±åZÙ¦Nêé陟ŸOÙ6BÙfœ­‰¯+¼z&•¯‚²M¡l³©e›Á¤²íìì,wÞØØ¨-÷õõ•ò„„loß¾ ÒìÊö£¶‚ÓUq·.d¿¬Þ¹”óàêñ—rª»—s›*cqo”mBȲͦ"”mƒ²=lØ0ÜöÌ™3uåH“†ràîí#FtttP¶íÊvB¸§Ãè‘ÒX`øëßôݶª£½Hö®^ñ»Qßycô›ÿyílšîÀÍŸ/•]÷.ç!±þ7ö»¯~þ©#þ–³á̇÷nËmÌŸ; ‡ïñ\­- Ø$§R÷†yâ±²]ªaÓx¶`¿/»1g{Ù¢™(1â±q9e›B(Û”mbwP¶7ïÜ„ù?ýË?ɦӧ˰9ò¿FÚx8ƒ²ÝÐÐ ·œœlÜ;fÌìš0a‚V¶‘¥œ²m‡P¶SãvIMøé÷« ÃÐ)}²8ÜqÞ{Rˆj­,Z{l^ŠŸ”GÞ¢d[õfc/æ`îû\õH¿¨l'ÇøÊ±èîÎI>€Aé¥9Aª—ûRã1Ê6!„ ÙfSBÙfP¶…––¹m$$×ízüø±ìŠ_”mʶº¦1 ËÅ8pmùôi?C9¸r:% ~û®l^?—®ª9}4%Cþö¯¥\ÉöøŸ8@ÚU5§9êXÛe÷ ^=ì›Cµ)Ó²÷ÉÙ"ƒ¶P¶ !d€È6›ŠÊ6ƒ²-tvvÊmoÚ´I·«¢¢Bvmܸ‘²MÙ¶óh>™ ´ÏûSÝ.¨¬ì‚Üb3;i¿lp— Ðih6J–:¾/%"ÛrˆnÒµ”#Ã61]åÚ@5£l«{[÷É|Ù«[>ûý_Fo£lBe›²M,@Ù.n*J.J>ÑRÞÃóT]¨Ì8‘^p*ÿ¹Õª/VÙ"Û•ç+ÒÊR«Z+»q3xœÔÒ”²æÒçÖ,l(°å„¥gJòOïÞ›)9]Œgyn5Ôɩɑ—CÙ¶ÜöðáÃuiÏvïÞr““CÙ¦lÛy ¥™4P}y”nWÉhÙuÀw­ô3£‡›S'ÿD*¤'ì‘ %Ù‡u²}¾Îdm®®]—MAz²­z°áêÖž‚²M!”mÊ6(ÛXçuίëõמñ·¾s0ü€ªð£ŸüpÄÈ?ûåð« ØõÎoÞ‘ÍØ¬˜ñ¿/'yþõ¬_%v“鈴ãÇþÍßþ bÜÏÇ}á鎋²˜oBMuÂïÿøû1™Ñ6>מàÝ8ƒ:ˆÇ„á몊ò—›‘øŸéSc´ܶ­Ç3ÎüÝLü‚€»Eµoø–íïq¬8yʯõoÿño8VùK¯/´‡„ Ã!¸Ûòse¿[ôۯͰ:›²ýB`¹Üù¼yó=z$…eee²ø6›”mʶ‡ÿîϤn_Ì6.µ%»6®_,%n«?”’›­YØ”yÝÐcÙ«•mL®¶"ÛÈLn‹l#›ì­*8BÙ¦lB(Ûlªç@(ÛE…c~:æ5KÌ[{zEË ©ãé'…rZÊv÷xòäÉĉåæ!ØH‡6jÔ(µYTTDÙ¦lÛ„ømÐNÌÖFQf 7®úºUWóÃkù2†Üs³³Q¶!êVdKy÷µ‘»Ë(ÛÈ^.GápÊ6e›BÙfS=BÙ^´bÑ×jýÑï0Ü=«!¦`ˆ¥¢×u¾Š’ÍUëWÊQ:%F—/6ò³ÿ+Â|86ö1(]ú«:‡åŸCÞÊW÷‡îƒ©î8à!¦m”máƒ?HÈKH/OwÛî&%è".=kmX8$Vj¢ÿ‹Š¡ë£²ñ€RŸ§º¾Uµð”0ÔÁó¢W_ ¥o_É6Îö]?öòó²ñdUfª_ö†ìÁ%ЉNo)ÄË×ɶ¼„ùKçãaÑ”íåáÇ...rÿ (7r•k«7åNNN”m{ƒ²­ŒÚ(´XgÛ¸kÌÞD r§%FyËÞ‹ É/*Û6&H+Ì£6¹-Ñ%u›û¿S0šÎOÙ&„Ê6e›3eB(Ÿ. öÖ–cN2äPÜRº£e"ª­aF![6¥ÿö÷K~¯­ƒ3Ëðo9N(æ‰Ù˪ŽéøÑ®dÛq¹£öl}mìy6FtF´TƒNk§ˆËSÀ–EÈeäü›ß}6®}vï=ùÝÉ:Ùž8e¢Lh·ýüfÎ éŸ÷Vw‚¡æò¼2…[É6Ι]•Åi=äêÕ«ûöí3™LçÎC7¿(Ûý%\hÞSu»f¼;A2Ë q Ìß–úÓ¦üTÍß~E²ÝÞ’¡Ö$³x?e›B(Û”mÌ”í­»·è:{UÌúýÿÊ.ÑË¥Ÿ,•Í”’cjz¶”xô”5êŸTÌèâFR1ü/‡¸ïp×]N:{²cuÙÎ ®ÒÝ-³ÍqfmHo°Ëíð#\TŽþpœP’¥E¤„Kt°ënfŽãõìZÙN/OSuly'rÙÄÈyÝ%||dWPÜa­loݳu0g#'”mʶZ¾K%B“ðÛµN 1OÛ(ç xï«“m„«óou÷Öz*uþà*”mB¡lS¶ e{ɪÅZŵ؇Œ!ÜØL.L’ÍÕ_ºjû{¡¾*Ñ·£Ó‡Ú±ÐïÍ|êˆÓØ¥¶Ùݺ˭ٴÆ(Ûè%6Þ˜äKCŽ1•Ã\¡ºÐè¯V…˜k¬cjq~ ýÛe/î2¬ Œ*—]W/Oj|K¶¼5p'Ô]Bz¼~ïÙV3À¹lÊ6eKXýׯ'× ý›“&üH²Žh­qeì÷ýsÙ‹NoÌÜ~¥²«ã–äXÜäþKþá›9g›B(Û”mò5”í©3¦BKÛ]““¥ä»?ø®ä “MDýÁ‚ÙÚÑÑèì5&ÃèëÌŠ TX»i­”¯ËÓ]ÎóÀ£l+s6öÃ¥%«yW²…ÇWÜbÖ7¹½lõÇØ´ŽôŠ‹Bc̹ñf¬¿ôZcÓ:˜›­•mëcÈ)Û„²=HârÓ18¶´”ÃÈo]È6V6EzKç%³t»âŽxÈ®{—ó´åùiþRŽkÖïdÔwÞ@5§9ªƒÉeȺ¿¨ÙÚ”mB¡lS¶ e[Í(¶ÜŒ¼_º1Òª¯¹ÊÔläÓˆN]ˆ:R|i—ÝÂßS­9Cšî(8§Q¶1wZWM¥aûÅÿücUpø¶6pimeX=z°‘â[¦a èåÆ.tGË&®…Ôåcέ˶õw"%2ý»«K`Ä;e›P¶)ÛÆxr³ølM|B¸ç~Ÿ5ÙIûÛšÓíêö ÜXvž_[ñ¨­€ÙÈ !„²MÙ&”mËF C6.-»¤QP_ %è †K+KWKˆÁ-£Ò"u ØÐÕ,GaÐ5²”ë}«@ªp£líÀo™¤:gA뮋›U{S³ÊµcÚa¼ØÔ):GsÙ´"ÛÖ߉Úûîÿ›¦ Õäs\iä”mBÙ¦l3”lBe›²M(ÛJ8Ñ'¬-‡`c4¸q ÷”_ÿJFMKG±ÌU–8}H;Ç[…Z"ëHR(ŽV=½Ú:ÈL.—3Êöï Úš˜w­ÒŒÛ2]åiÓåèW£Üu‡cB¸ØµÙ¶å ¤O§žK¸|î¢V£lÊ6e›AÙ¶/!”m6![’–A¨J[Šºçc0@$ M QS¯Ñ‹B ´èºF3Äi)Äü÷™_á:ðU‚ñµBÙf0(Û„Ê61ÿùŸÿ9ÞÕÇuå„4¥Â©öd¹÷ÐÍÐ=‹µ¯·í݆la°YQÍî,#«Ý¶­G‚qô!ÃfQhìïŪZ˜(¾+h—õ¾\é¦;†µÁðLüßöˆÍŠ¯Ùø)®…ôl˜n±2®£šûw ðÎ?u%/=òjsý"âxû{aº8J^ià#>ü÷ù…¸qãÆÍ›7Ÿ[íÞ½{—.]ÂÍ6ÐÑÑqñâÅ+W®ØÉW8¾Jp ¾V(Û e›BÙ&æø‡À»º~ýº®œŽÎÇ2m;óÙHr™°‡=üû|÷îݸ§´··›ûˆ)S¦à‰BCC-îÅ¿®®®®C† ‘ÇÓ¦MknnÖU{üøñ¾}û†.ÕÀ˜1cL&“Ù*nnnÏ}Ÿ;vì@…E‹õBáaq ¾V(Û e›BÙ&æ×_睊©É¸‹ôº˜•_ÞVJ&C|$ðÁ°“Ÿëêê䄿¾àìÙ³rÁÁÁƽmmm#FŒxÍ”ûäÉ“ªZggçÌ™3Qn$((Èܹ¹¹ªš•®æ‘#G¢Â‚ z¡ðU‚ñµBÙf0(Û„Ê61;88tõÿ©„ܺ߾Ѵr}"žÉÀÇ|$ðÁ l?xð 11*kE¶§N*{]\\jkk[[[=<<¤ý᪚§§§Nž<9??ÿêի談‹–ß¾}Ûbò°aìÈ6F˜—––¢{{M¶Ñ 8_+”mƒ²M¡l“¯ÿ_0""Ââ^BªÎ¯é§LƒÙ3éõ&ù$à#Ñûÿ>c3ŠwC¶!®è|†Ût~Û@Míxï®d»¬¬Lv­^½Z[¾dÉ)Çx ?tèPlŽ7îþýûªþY–jéééf3fÌÀ®®d[[èMÙ–{Æ× e›Á lB(ÛÄüñÇã]mÛ¶­« „¤ÕFA±¶%;ç4¥ NÏd éñÀdž^øz@Rë &@>¡ÐGþ^9 Š»}ûv ºVJ‰µkÔ¨QUUUj ôúõëµ}¿8Æ]Û~~º¯g?¥±±Q ¼Ô·.ÛÎÎβK— È?ƒÌ±‰Nl©–‘‘¡ë9‡–£Za¡þ× éô^¾|¹Å÷‰þö>‘m|•à@|­P¶ Ê6!„²MÌ>>>Ïýÿ0BBŠ|!ZL¥Ÿ::Ø<“FGÓã€ôŠlK5£4ÊlŒ‘F5c÷2Æ`KÞï±cÇJ‰±‚íçÔÀo9Vh}F^^^W²=zôh”ÏŸ?_•è4^ÀsTÃï¸+c5+ùHÉæëëkñ}^»vMÝ!ºÍ{M¶qˆ¯Ê6ƒAÙ&„P¶‰955UÒÞÚR™pÙmDÒɨÁã™ 4·´»,¬Ý˲-½ÍáááFüc…îh)<|ø°$'KHH’X¨ ǰm)D·0úº1çY¦@‹]Ûx~ë²­8sæŒQ¶e\º”ÇÑ7ŽNx‘^8ºÜµÓ°åw÷Þ{¯¾¾~îܹ’P ÿ7oÐ8Q\=íØ4ʶh|¯É6¾Jp Þ$e›Á lB(Ûäëñý×ýÜš„$U‡Šw.ð*;_LØ&FCK‹£éÍ /d»¸¸Ø˜ âÚ՜햖ÕA­í"vww—r,Lmûùe†64@tm—mØ»¾þšœÿôéÓRSìcàåçñññf «V­’npôÞÛ¡lã«âk…²Í`P¶ !”mÌo¼ñ^òÖ>·&!Yõ b_—ÄW†ÐHj qÑÄÒÖht3è Ùž>}ºÅU£•ÑeÒ+%)))f —/_žýL™¶õül—m\EÊ… 6`Æ8ÌY-ñ…N`L,GM娢ĩOùì³ÏÔ"aðv9'žH eò¹½É6¾Dp¾PÌe›Á lB(ÛdΜ9x]^^^¶T&äÊ­Ö#E;EÃöd¹ç4¦RMV.´T4«´/Ím}$ÛpNÝ®äädÕ#m”mm6µççï¶l—””H¹º7ui•H\ÊU5äf3kصk—”oݺU~,èë֭æÊ6¾Dp¾P(Û e›BÙ&_sðàA¼®wÞyÇl3„T¶x¦¸ˆ’…喙XAMíïQu±M)mŠÆE›…¾“m5wÚ˜L:®²iÏÒ!Üóó÷D¶›››¥³µu‡DGGË.$–Öfe»–jx"l¢O^M/}†Jx.›È‹Ö‡²/…/Ê6ƒAÙ&„P¶ÉüO!æÚI.\!äqç£äš0q³mÇV$ÕDÒWûo ùЈҚhV4®ôµl‹ŽjTË®††£l«„ØS¬{~þnËö£G¤ÜÕÕUwV“]nnnØ?~<þvpp½Æ|æÈ ¦ò¨YgÏž=}%Ûx¥2a_(”mƒ²M¡l…ÿŸ‡7†„½fB^–ëÇ·‰¤y¦ºFŸdî´þ• M††“DS¢AÍ‚È6znu»Ð-»`³FÙVK=,Ê%%*qÚÔ§TWWÛ~þn˶²\$—Mc—µô«£‚ä<3@îtu >f@Í÷–MÜC_É6¾>Œ?P¶ Ê6!„²Md–£ V$¤;ÉðN[-†Èß‘YŸdÏ’É@ä{¨&Có¡ͶÓ[ëlß¿ßØÙ‹ ÞÆläº,b7n4kprr’rd·ýü=‘mI‡nkk³8»¬¬ ›è]—ͬ¬,mµŠŠ Z_¶c¶ídζŒÞÇW e›Á lB(ÛèçbàÇÍ„t—Ú‹e¡E;5þöilEЉÖRû1Lš‚¦QÍ„&CÙ;“mé×½{÷. ‘»{ùòåRÉÔMFª0u,úWÅr‹ŠŠ¤óœ¥VÒ¶ýüBPPШ§TVV¾l766Ê®‰'¢7[ aÔ¸1)”\n/½Ó¢ßàܹs¸¢<~°sÙÆ‡Œ!ÇW e›Á lB(ÛD,{àÀ3!=ãú+u1*}š{‡^Y ÇúV2h‚À|/4‡´ËŽ”Uh¦¶;"ÀNe[@‡³8ª,  :™¨ ²ªæ]KµX«TÀLì=¿‡‡‡ÊLf»l kÖ¬‘½Ò‹>|øpu'è“WÕL&“ö†QSm†„„ ‚Ë6¾8dEñ.kP¶ Ê6!„²ÍœäXúÕLÈK¢æBIp¡êAõI_Vº?³!™ÞÛ›Ž×Ž—¯"¸Ð»¦µØ¬°cÙÆªWøGIkŘº|åÊmeooo”ë|]¬Ze•4cXŽ«ç÷ôôÔŽT7&˜´nÅ(W/àŠ8ʸHµôo+°Ð— ,·† Û(ÛŽŽŽ¯î;Od-9e›Á lB(ÛDqMKK3òò¸zûbZm”DZ•Jö6˜ÈÝW\p6‡2ü*/¯/¯Z½vc+ROF¢9Ì »—m1XŒÁŽŠŠŠ‰‰é*Cø7jjj0ôZ·¤–ÚF§1þMCÿs÷Ïßc0-.˜˜˜¨nÒ–þBwwXXXdd$þÀðò~ñŽ×+? tYƒ²Í`P¶ !”m²nÝ:.¸M^õ—+±¦ÔžL7q? ”UA…¾ÇjcO´–Q’{xxx™x¥Ú7¼7ëóc5a —«ÌŠþ&ÛÝ ×ÎϯpY^_”mƒ²M¡l“.¹zõêŸÿùŸãÕegg› yeܸw­¬9'²tÿ¶äåZ-Ü•éQæ—ݘb»a2ðºðÒðê´or[²sTéþòs¹7îµ™_”m~…ãË5ñůÊ6ƒAÙ¶!„²M\]]ñê&Ožl&¤—–énÊ®?ªVê–pOpDºl¬†% ÓO™J[Š(Õxéõ¦˜x9xExQÚ÷†×ˆ—yþúis¯@ÙæW8¾,P_fëP¶ Ê6!„²M0õñþáðö"""Ì„ô"ßÇT¦ªàk•=ªØ’ä´7û‹Ðâ=‰5y§3ª/V µÆcâañÈxp<>^‚ñÍàuá¥Õ^,øø¾Y1Pd;44ÔÜ-záüü Çתá+_”mƒ²ý|!”m"ëÜ ‘¯™>âáãèñ.=›<”·uKÒ2£dz¥­>tÜ#úD@J]\nSZIKaWk<ƒ‡Â£áOWqèøÖÄªÒæl¼¢Gê×±ÿ6’|ïøÊ0Ûe›Á lB(ÛÄÁÁ/ðÓO?5Û„´ß½zêÒ Œ‘Ž(Ý·+cÑB%¶&/ÇWr7}UèYîoªÃ(ôü3YåçKíA§q¸Ün ·‡›Ä­â†qÛ]=6¢t/—À¯b'm„/ÔÁ—…*¡l3”mBe›Øº”‹ÝfJ#äqÇ£óí§‘e-©:4´Èwö²´˜•øòè"¤éF"1ÿ¼mA…>!Å»ÃJöG–ùaZ8VÉ:Z–T™R›vêhfCRNcêñÓ™X@«ø\~ÙùâŠÖ²ê‹•üMb* *ã¤ÇáG«àT8!N‹“ã¸.‡‹âÒ¸ëwˆGÀƒàqðPx4<࣎‡üz vØF’­;KER¶ Ê6!„²MV¬XwøÖ[oÉ’°ö!O:‘|ûüõ¦Ú eEgÒ±¸wL¹ßáü»2>Ûœô1l¶Ï·›Á-áÆp{¸IÜ*Fƒã¶qóƒêëÁþ!Vf¼ã«ð5Í!Ûv †™B¼ls0ù‚ Ì„ ˆyà×î\:s­®ò|AñÙÌü¦”œSF]LJM8f†Çˆ*;V¼;¸Ð;àøöƒ¹±<5ry¥~²=ÙySâÒ/"ðVÕBáÎôµ¨€jÇ·ãˆÃq’Äªà”“u±89.Qr6—ÃE¯Ý¾$ Ì%¶¿Ëö‚ z4€œ²Í`P¶ÿ?{÷ »®×püP7‘ &ŠÅd!QÌ LT‹…¹Y¬ÎY½½ÈXLLn6ƒÙÍY)ÞgÃ=æßŸÏ~}¿z¢½w.ç ¶QU•eY"’¦)_¦©ˆX–UU•ùDZ ­µ4ò<7€/–ç¹4´Öæ_Ä6’$¥TY–æ+ʲTJ‰H’$æGbQ‰H·Û=æËŽÇc·Û‘(ŠÌÄ6‚ ×u¿­·€Òv]WD‚ 0?ÛFÏùö÷¼'^?gÚ£ÑÈü§±Í|[)õ ûÒ€hJ)fÚí€ØæÿmîÀ7\ùâ?ív@l³Ÿ¼Çñãñ0ÀãñˆãX­îÄ6´Ö–e‰È`0Øï÷æØï÷ƒÁ@D,Ëú…{Ú€ØFUUžçIc>ŸÀ‡›ÏçÒð<¯ª*~ ±Ùl&~¿Ÿe™| ,Ëúý¾4f³™¿ŽØFQ¯÷x<æU9|Ö»ññxühEaÀû ¶±^¯Ç‘F†»ÝÎÞØn· ÃPŽã¬×kÞ±ûýž$‰mÛÒð}»ÝÖumo£®ëívëû¾4lÛN’ä~¿ðΈm\¯×ÅbÑét¤¡”šL&yžs$ìwà Wžç“ÉD)%N§³X,®×«ŸCˆmh­‡Ã¡üŸR* Ã4M‡ƒ´âp8¤i†á³±Ÿ†Ã!g½øHÄ6^N§Ór¹|mP{…·ïûq¯V«,Ëʲ<ŸÏ·Û­®ë¿;FÖu]ßn·óù\–e–e«Õ*Žcß÷_ýäyÞr¹Iååå;;;½Øðöö¦ÀÅÅ…Á•þÿˆo&''XZZ²ˆÄ6€ÙÙY¿ïlaxxX񮮠9„µµ5FFF¾¾¾ €Ø¢áááAÛÛ[s’ºººÌ'är¹ššI­­­×××@l011!izzÚÜÂ_ªÝÜܘOx||ìíí•TQQ±»»k®b@>ŸWàååÅÜÂÌÌŒ¤……ó“¯ÿ–——Í/@lH$’æææÌ3œŸŸKjll4çN§ýþþ6Ä6 %ÉÂ!›ÍVWWKjkkó}5Û± TÏvwwKª¬¬ÜÛÛ3± „~®°õÅbq||\T*ebp0WØúÕÕU’Éäïï¯÷ˆm0ÖØú8<<¬ªª’ÔÑÑqwwgÀ=bŒ5¶>îïï;;;%Åb±ýý}‘Alƒ±. '''+++ƒƒƒõõõMMMccc™Læìì¬X,þcï ‰Â8€/6 H!„!T!r€ˆB(èD )(’HA¢PREIÅw=žvwz’ë\·ßLÓ{½7Ûgùϼf®[Îf³øE¹\¦ÛR©Ú$“IlÇD"!zm6Ò‚ðn:¦;Ìçóp8ìt:F£^¯·Z­^¯·^¯Ó_·ßïC¡P0T?Ç2™ šU«Uz)ëõÓ†årI·åóù¸|ï¹\wÃ:ŸÏ¤„r]Úí6iFq%Q?­V+~Ÿb±H’‡Œg’qØþ#P!n·[Ìÿˆè?ÀcŒ1ÛŒËz2™ ]‹ý_9$®ëX.ö#“‹þU·Ûml6^n·[ñRñÈkŸÏ‡w R6›ÕétšS5›Í‹Å‚žf·ÛýºX­Vb†C×j5RŸÍ½”ñx,p8Òm‹åM _™âlÈétB9Éz#-¥RI=„¨Ÿh4úv»ÝN’‡ì÷ûé PN(3œÁùnëY"‘ˆ˜ªËåBUcŒ1Æ^‡mÆeÝétdÎÁnS‹Åps`d™i‘aúý¾ìâñxÄþF£AZÐ]4ÀUM¶%\º|8l7›Mù9èòóò‡=Ç`0£àò©fØæ°mþèÓIœ[«!*•Êu3¬\P„m”¥þL+~|$?öÓ~”Í?¶E=c]À7üñH¡PxÇlM&S¯×#ÆcŒ½"ÛŒËz:þfï <¬ú¶8þð“¥?ãAI A©&JQ^ŒR¦¤H&QI©ªšè™R©Šª™*˜Š"ê婤h¢ "Aû}¼Å×î®sŽÓ¹÷MwfÖ¹÷Ü}ÏÙçì}MŸ½¾{-¡ÈÚµk‰Z§Lïß¿DA2¸Áeù¶ƒ›6mJEÂÝm ÀlÛ¤A"fÕ ¶éáÖëׯS¦/_¾`€·ó«lïÃvÀ6›œXû8xð`u0¹§§‡O¥ãÇWÀöÝ»wÓïhéÒ¥6g’WÀvWŠ4isæÌ±Q“Û? …B¡ÐxRÀv(¦5ìgowîÜYæï5JDø·[L¿ü«½¸ÞCήï„l£#GŽ4€m6HÛ×± Wp___rúùó'k£££ÿoØÆj.×}lÓŒÝïÉ«Ó}öbaBþÿŠ ´íö¿}ä×YØ ®bË6¯È•Õ=°ÍóX2è8lsfæ@3ØþöíO²æUX&wMè3.ë6åÁR( …B¡q¤€íPLëOŸ>É=ÎÿÝS‰ž>}j͈Wëà¶mÛìàƒÊ<äJ&ØÀi{ýîݻ߅mß¡C‡R‘H™ïi[¸™€*¬¥›ò|à[hdd¤%œ'U²\çÇñ¸ ¶¹Ù£G’ªMÏj×®]в‡mÑ“rDãÉWî±ú}FDòéƒ/^¼˜ãfàGd¹ã-  ÷š5kp(ØuéÏãǽKŸ 3—3C8Cɽw¶7oÞ\f?qâ„}ôêÕ+ÆÎ^óþ,lƒ²$á³ÇeZ°`f»‡mrzqû«W¯N¿j÷îÝ·f¢_nSƒË ÆZ÷»wï^Úë#^k‘ ½yó†,bDæ¶ùFÅ9·Ÿ;wήríÚµqúׄ§§•;­u»B¡P( l‡bZ߸qÃÅ™‹%‡6L.Ÿ§éííõrãCEÞÛ!`{½dÉ’ú°­p«<íÚC^­ëׯÓÞ‹î=Šá½§zÇiK ©`Ûª‡#Ø6@*ì œY¿Ï&‚·$踂¢pÁ¿ï!±u¤ùà/ÚØf¸ËÆ×–`{^“@Qî?Ûx´Âz!l³ Cw‘‹óÏëÌöñ¦Á† ZŽ“ó\ Û çϺuë`l™öíàúõëÕ`üÂ6ºtéÒ´iÓèüܹsõ«ïj…B¡P( ØÅ´¦.—½J•¢º•µÌÿ³ Y ª½‡ÜüÒ¶y»råJ{{óæÍš°-ÖË#øÉŸïß¿—hë$„† W6ñg}Ès}ئ´cG(ûD(°ljß&NN—T\1‡m±\Žsr—-[V¿Ï `[áAFë2:â4íÞJ¥ÎWŸ7oGÚß³MÊ+å´Óqîûh``€·D/ ï¹ ^Â6AûÿI~ûöa{ûöíê0=$—¹Ám\HùÖl3.væÁÁAüü?~ü¸wïÓ^OÈ?d×"'¯ifþ -ëOŽf”ªE l ¹ùÑi†§ñ)Ì5³gϦÿÓ§Ogá u¹B¡P( l‡bZoܸÑ^ãMM•Âj-±@ë ^nE½‡œÿ—Á¶x cj¶¶ªÂ3…E¿ØØ‰ñ»ÐºÜRB‰æJŽ]¶«÷lsG¹êÖ%Û…W/qòš}nÛ 'c9nÙ½g!çdV êÃ6aã¯Z´h‘Æt÷…Ùt]CJ„ã];ê—þRͰöa› vB ü2ŠÛq¸·1lcò÷›Òo;3k+e{¶©$owÁ²ˆÒ=,Zól+?aþšp_+V¬°»èïïOݬP( …BÛ¡˜ÖÊ?D²®T)b‰ù6lÅB}¸ÒØLÑ?Û-'ܲeK}Ø–™Ã3áqo©5ø1@vr›éWµÆàS§`[¡E•.WV¹¶!´²|r¸Çkö¹lk €¸A𽵇IèÛ¯³´_gÛ³Ÿ6ÓöMT†³öªÿl_¸p¡p>|üø‘烞?Þ¶eë8}ú4h-ffÕ ùiJ•gß"ä^è®×Ú„`8ŸxMØEo7Âc”Å£ë …B¡P(`;ÓZ^Y¨2UJ1=̺)acQ5q#¥ž*`ÛàA‘^ }ׄmIˆ‚)šQ9x‹{EgÏž-ËöŒ)½#°-¨–°ëê9lƒ¾þ.ôÐjö¹lûK".Á6‰íº'Ož,\ ¨Ùþg&h™¬rŠûíÖ%ävƧmÊëiçtœÿw‘òm¶5ÛuB¯Æ°-˃u‰¾ñ£µ¤ ¶µ°Å,Úþ«,âX#ȧ=«$ò¯ ;8¦NjF‰/^¤P( …B]¨€íPLk Å^ß¾};UJ1p@Ò|íø;wä!¥TÀ6Â&m±Ô¬l7.î c€Ö|4^Š ]*`›f}ØÖUªaÛ1YíØ±£fŸ«a„ó° ™TÀ¶ÒÝYt]ÒVá6¤‘ÏN‚g>e" ý·JÑŸ±OF'Õ¾}Øæ·#ØV":Ÿ¬?¿"ÿ¶‰Z«¥—Bå9l_½zu¢þ5yòäɬY³¸3fð0S( …B¡nSÀv(¦5™™ì5{k«ëôúÒ_ÚA­È¤<älÓåulK¤Y¶ãÇŽ«†mÕçäöeí„$ÙÖÎ[ ¸} UÀ6»£ëö¾[ Û\ÑÓVÖ´š}®€í¯_¿rÐÃ6XÛ‚|VOZšüÝÉ>"0>ö°MÒ8--µÛPtÛ²3ư½ÿþÂŽ1ëþñ?±”SÛ µ_Il󖙉ò, lÕÞºu«6#¶|þ¾Ž73ÍÎ NØ–Xi²ûZµjU …B¡P(ÔU ØÅ´–“¢˜Prb­J[óßúä„Ý›‡š°>|Èq©¶åZß³gOr’-YÉÀ0¨Û9±©§LtÚݿŸ·O¨ ƨ‡mdéµ$ÜãvœSÕï³`O!SÕ¬jÛy!7ÀÛoËo¶ýb \êK|I<7m#cØf([Ö5ò'‰°xØÖ fŽOJoÃûu+²Jj{ØÖÚ w‘O ðÓÞIÛèüùóS¦LáÖæÏŸÿòåË …B¡P¨K°Ši ˜e×@ëÊ•+d~ .B©Ø\9®šØe¹Á ܦܰ-†©ÛP±²mõöö*û·6–+µ5fl;B’*îHŽ\³4KüÞ¾}k D©WBk>µ#âj ÛÜ‚Êz]¾|ÙRñëwûláP]š‡£Ìá `[¥°yŒt¾Åçß>l«@ºõ…É$Ú*6ưMüÙ–<ø ‹Av ÕJQæm䲨¶|~Aü.øŠš`[‹)<(ccµ£­Ù­[·r´¦¬—Úh]Œp.çW†9.aÆ„&lËÍaKE3gÎd’¤P( …B]¢€íPLkÚuô„û¢M>š*Z¨Ûú”KTö·I«oЋñì5ÉL0Iáwã(_R©3<‚mQÎ7€m]%¿kòýnŸyÔ¾ÏÍ`[ùáu!œv§üÛ>l+Ûpà€µ!f^ÛØÛâ4«#%sŒ~N¼Õ[²µcÙ‹þÐ@ù󸮭Œ¤rYzy-à­Èôõ…ÓA°]_Œ¾Ñ¬]ÛJn¹¥–IÝí¾4!ñx÷÷÷ÛïHͰE¨D'µàb´ÏhŠ5@}}}úŠrZ\“G9ö&Û_vdÈ’B¡P( u•¶C1­ù_;´Fb°‹/r9w¡ÈV5<<<00@yjÌØp¯j2{A³CCC§N"®ˆáœÅ…2›:\ͨK²UQß[çi–K™H8m³ÏÄBÁBÚ@z²·#èNãyºè¤¿ž-+)V »Ž,¦ÐÈÈ–Š)DRÄÞ,"øð¾,™Ø « öô‡B_ SK…üøk288ø×_ÿeïŽA©ûÃŽ?ò߬Ù“nöIÉ^÷$›…åHÙÉh—`—Á¾!v¤3YX 21H²YžýîÛ»¼.êf:ŸÏ>>Ïð=užß½¯Ke‹ˆm0W€­ošfjj*"FGGË¥ ``bÌ`ëßßßççç£ØÚÚJàçÄ6˜+ÀÖÿäpc]× Nlƒ¹l}ïÆÞððpï¸]yo˜ØsØúëëëN§Ó;¼||œÀïÛ@+e+½½½ÍÍÍE±½½À/Û€Øn™(–——øKl///###q~~žð½½½ˆ¨ª*á3‡‡‡CCC133óç‰r@lkkkRŠ/<==Eñüüœð™«««ÉÉɈ;==M@lCË=>>Fqqq‘ÐG·Ûˆýýý„>^__«ªŠbgg'± m¶ºº ýEÄôôt—Ö××£XYYI@lC;ÝÞÞFqss“ÐßÇÇGïÇþ»»»„/D1;;ûðð€Ø†¶Y\\Œˆº®¾³´´››› ß¹¼¼œ˜˜ˆˆñññ³³³Ä6´GÓ4QÜßß'|çää$":Nþ ž9èv»Qìîî&üÏÞ@´óÆq`2tYS„‚‰4Û d *«+D¬™ „*s%D ¤vMCÀ¾ÿ¯û@·]lû½_`xŸóx0¶D6›5Æ8Ž#¿X–Å]zdggÇøVWW0¶¾çº®1&‰xž'¿lmmc666ä×€““ã›™™y{{ÀØúX:6Æäóyù5àáááÿ‡”âþþ~||Ü3<<|}}-€± ô¥jµªýG£Ñf³)A“““Ïåå¥A|}}ÍÏÏŃí0¶~•H$´ÿB¡ @@ûûûÏââ¢ÁmooßúúºÆ6ÐO*•ŠÆoYV«Õ  ——íg``àççG€àŽovvöýý]cè¶mwrŒ˜žžÖ„ÎÎΤ-ÀÝÝÝØØ˜V422rss#€± ôºÓÓS-bbBÚiEsssÒ. Ñhd2ã+‹Û@OÓ™­åëä–vßß߯÷ññ!@Ç1¾\.'€± ô¨ÃÃCÍÞ¶m:³°° -Йr¹l|Éd²^¯ `l½¥ÕjY–¥ÙW*:s~~®-MMM Ð1×uãñ¸‹ÅjµšÆ6ÐC …‚6ŸH$$ àÛÍàà õüü,@Ç>??S©”ñ•J%Œm '4›Íh4ªÍW«U °¼¼¬EíííIH€ÍÍMãÓÛ@÷Ëçó|:–WWW¡ßl”J%ãK¥Ržç `l]Ëó¼H$¢Á»®+áFGGµ«ÛÛ[ P«Õb±˜¦Çù×€± tûÉÌl6+¡vww5­µµ5 P¯×“ɤñ•ËeŒm Û¼¾¾ßã㣄 xzzÒ´†††ø¹\ÎøÇÀغÊÊÊŠ¦¾´´$À°m[»¸¸?‹EãËd2Fã?v(ŒÃøÉ…I ³I"@$Y)¤ E Ri) @Ô’‚šš4@1´,¤•@U]™J0À÷ºøÎ{r=?Àã/^í\‚À± ü Æ÷ôôD ذ¶¶&'…%(•J---2³X,vuuE8¶÷&&&¬>©^^^dc¡Pè÷÷—–àã㣿¿ßø²Ù,AàØ\*—ËÆçy5ìA__ŸÌìàà€VannÎøæçç©Ç6àL*•’‘§ÓiRÀªl6+K lÛÙÙ1¾¡¡¡ÏÏO‚À± h+‹²ðp8\©T¨«¾¿¿ïýý°íâ⢹¹Yöǯ¯¯ Ç6 *™LÊÂWWWIccc²·õõuR@çyµ?qbŸ plJ …‚Ì;‰T«Uj@ÁÉɉL®³³“P333c| Ô€cÐH$dÞ™L†PÓÐÐ «»¿¿'Ôlooßðð0OfàØìÊçó²íh4J hšžž–á---‘šÎÏÏ›ššd{­­­777€c°¥££C¶½»»K hº¼¼”áÅb1R@ÙÛÛ[oo¯ñår9‚À± ürc˰åÞ&ôÅãq™_©T"\ý¶B,..RÁÛ€²h4*ÃÎç󤀾ååe™ßÔÔ)œÀÖÖ–ñ¥R©¯¯/‚ ø€cБÉddÕ‰D‚NàááAX__O WpvvÖØØ(;lkk»½½%8¶Õj5‰Èª …5àJWW—Œðøø˜påõõµ§§GvXWWwxxH@ plëVVVdÒÉd’phccCv8::J ¸599i_È Ƕ> R©„Ãa™t±X¤ò<Ïøx1 ç677oddäçç‡ ÐÛ@¤ÓéÚ7Hçe{{{¤€s§§§µ÷5íííwww>àØ‚ð¿Är¹L 8—ËåxÑ€¿ãùù¹»»[6 …ŽŽŽŽm%Àì쬌ù{wÑ^Æqübe"M U6$Å0‚TÒ¨É!ÈL K #€’A’  BR‘e @! M‚{Ÿ÷qn/ÿçðýŽ/úuæÜB¡ÀQÀ‚v»H$´I9œŒX[[ó"[[[œÀ>Æ6ðï5 /òôôÄiÀˆB¡ MV«U1¼Þ§æææ¾¾¾Ä.Û€ÅbQKÖK̸¸¸Ð,3™ŒXø¾ß××§qßÝ݉0¶-ôE/òöö&€%¿¯R±g`ÍëëëÔԔƙH$NNNsÛ€óóóšñÆÆ†Æ¬¯¯kœ›››ØS*•¼H¹\ al\__kÃsss£} `Òþþ¾YXXh·Û€ ŒmÀ€|>ϵ ,ÒD¯®®0éòò²··W+½¿¿ÛŒmÀ÷} 8•JµZ-LªT*Zi©TÀªf³999©¡vvvžžžŠû`lÿ ËåŒZ x~~ÖJ»»»ƒ ÀÕÕU/R©T÷1¶˜êõºÖ›N§Ã0Àß;ó³3± ØÛÛó"‹‹‹ßß߀ËÛ@LÙlVë­Õjbppp ­ÎÎÎ àÂ÷áS©”;66öðð 8‹± Äqtt¤éŠyÀûû»ùüüó€———‰‰ -6™Lºû‹ Û@:³5]ܸ`ffF‹=<<ÀÅbÑ‹loo‹}0¶¿«ÕjÚm6›ÀÇÇÇíôô´î¨V«^diiéççG쀱 Ća:ÖnëõºŽÐ¡’L&µÛf³)€;ÎÏÏ{zz4ÝL&óøø(–ÀØþ~Ó’ËåpÊÊÊŠ¦»»»+€SÆøø¸ÖÛÕÕ翜0¶íZ­Öï3¹¾ï àVÓÀ5A,//{‘± Æ6C¹\Öbóù¼êïï×€oooÿ¿ÿدCØcâ8ãWþÁÎõ 7 ª^˜ Ý ER(:\/z¨H Er»™ )·Ùô³ïûݯo—Þí~ö|z|Êóß!Çð}ÿý~K6˜mI’üýýi±‡ÃA Çc x2™ˆ€Ífãyžf\­V£(’ 0Ûö£ÒétÄNÀétÒ†K¥’ÖŠã¸V«iÉÅb1 CɳoÀý~wŒóù,€µÊå²f¼Ûí°Öçóév»Ž±\.%Ì6WÃáP[ b3`>ŸkÉý~_,, ÇÐñÖýr†Ù²].Ǹ^¯b3àv»iÉ…B!MS±†¡ëºšt½^ãXÈfÈæû¾†:Ä~@£ÑО×ëµØˆ¢¨R©hÒžçm·[ 7˜m ÃñxtŒÇã!öV«•öÜl6å'išú¾ïAH˜í|Z­–V:Nå'ÏçÓ1’$‘_Ìf3ÇèõzßïW0˜íœöû½&êºîëõ’_´Ûm û;wÀ¹:Æqü(P &A°èM´öÑÓÀ((¡‚è] `ˆsg×½äúåÖñý€9~°Ç?‡³Z­”F€ív[.—óÝîv»<±(P¶?0 òÏçJ#Àz½Î»×ë)½×ëµÝnçë]©T’$QP¶?$‰ˆÔjµ,Ë”F€Çãñû çÛí¦ôdY6¥°X,”màÓX–%"A(@;®ëŠˆïû БïûRpG@Ù>GÇ"b†Ò°ßïE¤Ùl*M›Í¦T*‰ˆeY÷û]@ÙÖOš¦ý~¿Z­Êþ½\ÊOÈüߌiš"Eó!£wf<3]3dÎçs½^g>oÍñ<¯_˜L&aG”íwØívaþô§ßR¶ÉDQ$"¦i2í3d:óÑ8Cf:2Ÿ·fÈØ¶-Ï–Ë¥Êö ;¶ã8ï®Ó4UχCqˆï`†ˆÄq¬}N'i4 ÐÝl6“‚ëº x©4Mß÷G£‘mÛ—ËE=+Nh²ý­VKþÈ¿=Ï£Wµ ~±wí­aÇù„•Btƒ’` H¦ L )œÈ¤B‚I-(ŠLh…P„2IB$5A¨¥*JUáBÏ}œù»¸àº9Ç=ï÷Æû¼óþ¶÷}žÂ?‚®ðõµ½½-@Э¯¯[–ÕÒÒruu%€‡þp¥ÓiŽˆ@¶=å8NMMM2™¼½½üÿgÆè¬/-K´ÂsssZ탃ƒbàìì¬Ð£¬¬lggG¯þúÖƒ¢å²m;•Jy¹¶ÿÍÎÎjMvvv `€|>¯¯÷}}} `€ÏÏϾ¾>˵¸¸(^ôGüÂëîÂEH@Ø&lÿóéµ¶š”€ÂóósII‰Öäþþ¾fhooךÏd2#‘HX®ááa¼=Ijäæö`Âö¿¸¤1Ûré¥âñ¸®o4À…ÞûÝÝݘD[`þúõK‹¿µµõúúZ lû"—Ë…Ãá¿G>,×ÑÑ‘Æxyy±\˜äôô´±±Q‹¿¢¢"›Í àúþþ#lûõÆÆ¶í¾ l||\Wy``@Ãôööjñk~ óþþ^¨¶|”L&mÛæ9à ¶ÿÈ5f;ŽCëÈ»¼¼´\fss“qw0Ùôô´åŠÅbø1ׯr¥R)à?¶·ˆÙ744Ä1 &+--åÇ&˜lmm- é.ˆD"777x+“ÉX.=€` l…g{–+ŸÏ `¤X,¦[`ffFSœœ444èF¨¬¬ÜÝÝÀó¼­¿{Ò¶…™«“““˜êàà@wA]]{}}íéé±\KKKxÞ‘Wƒy¡aÛÓ6æÜáÁáá¡aQQÑÓÓ“ ¨­­e´! ¦¦¦,×ÈȈ@Øþñ73¹\N €®®.]îD"!"cllLŒ¬®®Z®¶¶6‘Û?s{Çr2}ÙlV—Û¶í1p~~®Û¡¼¼\D×××릨ªªÚÛÛÛÿ¥åx8ÖÏã8Ž˜‘HDW|~~^D477ëŽØÚÚîÁ Z®t:-€—,xÂí=€°ýó&&&ôÃèHm1666tÅ«««¿¿¿EÀ‚nŠþþ~ð[<·\£££xÛEH O¨€°€¶Çá©¶9ššš´ü–——ÅàîîN7E(z{{¿­¬¬X®ŽŽŽûû{¼}ÞHëJà‡¶þÅÞ](§Ñvqß øô ÚKèd¬ã½†väÓWêîî» 1Jã „`‹kpBÜ*°iÜ÷=ó2eê.YòÿÍ©û>óŸ³g›}žõåçó3ÃÏ‚޾ƒ=©1'”ì@§¦¿¥'ÔÔå—´ykäîò&g‘Ôv¿Ör³Òx¥T¾P{ê^ïÑ[=¿_ëþ}…¾Y =E?D?¡Ö|Sb»×è(|è.kõTwúÅŠ`£:"×GÛMñnÛ`¯kX™ìK%Ò‹O×7Ö>pçD§YÒûx<¼bïÞ½ûç_ËEÅÛ3¹?‹Õj¥³ñ†9vì:ïÎ/þs{÷îÝ< †mø6·6g—RãédtÊK½VmëðÕÕÛóËØ‹·U¯<þ÷O¯»ªÃ†K Ž‚NŸHm§¿dÿ”‡þ³KÏS\ŠFnàHîµ®ÿoóänl®ó?@*•Ú·o:ïÎ/ìÚµ‹ašºù\€aÃ6¬m¬NpCÞQ³*,“¹JªMר¸Ý^WüÿæD™á²Èz¯ÁYÜì.—÷U·zëÚýÒ®`“"üPiUG;u1…!¡2jmCLjÙ=f÷N¸“Þðt*0é£oÒw:G,ôÌI­!Ñ«)4Ñ.U›2,lîð×·úD<52wE£³¤Ör§”½xO}ŒÏøoHOîé™==à§GþqûôìØæÖŸC\áB~°,+¬M…ÃöÇ·ø,6ã7Å-žÊ2öÂ{`÷)ÖŸ¯±Ü¢^K}—z°>¦´}žÈLø§—wÂM7 ú˜B–·zE Î’Ëíýyúk_íþÏ;ÿEô<¾ÕSmN(c3ºüÏ€ä"¹€ü"¿ÐÞÞÎ `Øæ8îÀجm¬Œ§“žQSO¨Yl»{Guèí^X¨;#¶=h÷K4]–¤®oÜI=UÐåwY‡XzTOOýë¬wóµ§ÞþWßQ[ïÐûiîÃh*±¼¶È ¹H.ò‹ü`Øþè¶yyy;v³è´Oj*eÏ¿«Õ®4]“¹+z"-ÔÃÓ!ê‘9_¡©€%©W†åÍîòJã5ºo_™rÃ%UX›ñÓøño@r‘\äùÀ°M»;îÀ&ÒC¦¸‚v}µ]íþo‘î¬Äžßá—êãJzðœi(ºl\I/§IíÅúsׯ½&µß7'”ôN€ä"¹È/ò €a;ó ýé´Ç#¿ÐÎ¥¾1K›§š6&yµcÑ*-Þ:Ó ­ýÓ˘P?òÔ–²—ÞØñ¥ÕSMÛØàe³ ÉEr_äÃöþýûéOÏÏÏçsWâIH‘Ó¶Ÿ¯6'Ú§”v+QG;ý“^ôï¯)ÿ¤Gí í^é’¾ë£Ý<’‹ä~ €ü¢_ŽãÄb1Î ÛÿøÇ?èOæsγùimëõ±lº¡ü•ö¥c?è„´êïQtaéòÖZnßTþš½ì÷ÕGi!žÍOñH.’ûùE!¿tËÊ0 ݾòÛ`Øæ8.÷ŽRˆLºéìÊlË¡£AäžjC¢-ùG–1ÑKG–¼rj -Jdª@r‘Ü/È/ ù¥Ó¶†Ùþ·¯Œ@ÿ)Ã6¤ž°ù/?¤ŠÎ±”Ú 5ºïÏ-z%¯ÞQH[àdÖ¥@{Òë«e€ä"¹__ò{ðàA†aès Ûð#†mÀ° Ñi¯ÌUš}ŽKûšvü“´ÛíSþI/- -Mv™äîòÏz¯ \’ È/ ùeY–a˜={öcÀá®`Ø×0[¤;“í"ûC\…þº‹÷ˆm²KV¢?oOjøí\’ È/ò‹ ƒ†@À° ãéÁìYÚÓí~©w†* ãCÛ|’|ÍÉÌ Š¬wFS þcÉE!¹€ü¢_‘HIJ,Çqäà¯`؆õ͵ވ<Ó*î©©"­è Â-u´#{r‰:"ߨ\çÉE!¹€ü¢_ r Ü5 ÛtD¡OØŽ; ^>”•¹+BÓAtM¡Wx&$sWfÖ´P{:<éâ \$_ò ä°F€a;//þ\–eyx:7ùðå^,Æ«æ¤Í2—Ê<¨-7\ɬo‹§*-ÔMSÉErùE!¿€A.k¶…ÀïÎ4ƒ›=¿=6£Aæju¯+þO }]ñ?{RÍ;€ä¢\@~QÈ/¹±±±;ZZZâ¿©­­­t:½¸¸ÈÌììì‹/þ`ï¼£³¸Ò4ïÿgÙ¼Ì6Ñçðg–Ùq&±ì°L³´ÛÍи{YÓ°Mƒ± 6 ƒ Z6Á ‘Dd‘A e$¡,P„$¢È˜à@Ì>Goûžê¯>>–Vø=ç=êÖ[·nÕ­Gï÷ÜøáAΗ/_ViÛSÄö?ÿçÿ\÷µµ%Ú8Rª,ÞkÓHÖbéðVz¾`Ãáh«ñCµIÿØJ0ƒ¹þbð±™™ie»råJ˜—”””È¿GOs¨©©yã7äcèÖ­Û„ üª[R|Ê”)]ºt17ýç•W^9wî\ˆ[Kf›ÿ’%KB¸ 4H> ˆíïÄ6'v‰³¿þ)Çw;8¶Ýê½øL¦ÿ«0ƒ¹þb™¿ýšð|î…Ø3fŒIèRÜž={Þ»wϹݸqCrÝï&-}üøñ 9?~üø¥—^’Oh±}öìYóÙºuk«#€ØnÛˆ/ŽÕýÙÉïfžÜßÙb¶·ò3‹ú• Ÿó‡`.sá/ü…¿HYÄö™3g¦OŸnþAŶº¯»víjëÖ­khh¨««1b„¥ÄÄÄ8ÏÁƒ[bddä‰'.^¼¨³–¢~é w_´h‘ΆÛ÷ïß?pà€T=bû{± 2NìÔŸû©¹§2ˆÓ¶—ÇYÔ¯½Z #`.süÅ:<ÛW¯^ ísýúõK—.…ãÓl±=þ|7Þ;„Ø^ºt©MMMõNÞ¶Nì¾}ûZJyy¹¹M:Õ{ù¸qã,Ý?æÜ]Tlk&l÷îÝÝYÄö÷bT](²¿õ™µÉD¾Îlñ%+ôÌÞÿnÃÍzxs1˜ à/ÖÁø‹ØVO¯†Ä¯^½:??øðá&qÕ]¬ÁÛn1§Ÿ5Ú;çY£¬5_:ŸÐb[›6L=Ò.E™˜[h±Ý«W/¯¨vØ»wïØ±cg̘a‡–IÀi¹Ü 2÷¦óÍ7&×'MšäÛö˜JDl7ˆmðÕ½[s’Çêý®£›ˆyئ‚EúbNÒ‡;`nG2˜ à/Û §¿ŸÖ5ÜÚ-ÊmúÓìììp|Bˆm ä(ðW_}¥[lñ3¿ØÖ‚gvÕ–-[\ŸvÐg|ñÅå6jÔ(ï|ìïdôèÑò—’׬o¿Ø6¸â©‘±ý=€Ø™5»õ'>.>Ñ3[›7OŸ„> Øs;žÁ\1ø‹Ø6,_¾üÔ©Seeen|õÈ‘#ݸn§l¥rAŶfw×ÖÖÚÂÛ‰‰‰–•Ý7/µo]Ð.Åï&á}úôiï6à’ë¦ÌuˆØne ¶Aá©týq_™Eœó¶"{VÛOæb0À_ þ"0\‡pÀÈêÒÒRËd÷îÝ:Ôtn;\³fÉfA—|Ý; íæiá‹mÍ3÷Îè^¿~}AAA||¼ ¦M›f³íÐ0{öì¼¼¼}ûö :ÔRúôéóèÑ#yê_õŠ+EóÌUlÄ6b›­¿žÕöžIUŸä0¯í¯NÔ‡±«|>s1˜ à/;’Ø–à H—<ön ¥å¾½{S2dÅŠÒ™Î?LŸVÛZVÍõNkÔºwy39Û)égk50z{ïm6¸Kÿøã­ä¶Ž:b»õØFl¯Ë›£¿ì9<’ ÃrêêÃX—;G €¹Ìðƒ¿GlÛÜlln³vº¶Cuqû×QS7²ú“Í!´O«‹m‰[ËJ¶-Å¿˜¹†¦Ÿ;wÎþ¯ñn»ví²Sê׿Ûöÿ)S¦”y`‰ÊPÿ¯¬¬Dl·ˆmĶM+k(&Èa^+o(Ö‡¡ÏC €¹Ìðƒ¿Il{·Ýrÿõ&–””Ì›7oàÀÞNlMuÓ§ŶV_³¬´ìYÀ©ääd;¥©õ>t*:ÀM;Ù©Y³fÉó…°§@l·ˆmĶmòYp&‡ ‡y­ðl®}úHÌÅ`.€¿üíHbÛ­î eÃ,ÍpÖˆëò&ܹsÇ;Î|òäÉæ³iÓ¦p|ZWl»nÞ¼9àÔÎ;í”-~¦kƒöÞ_½zÕå ‘äróÃ;-\o ±Ý @l#¶Sï$Èa^K;±Ç…|s1˜ à/Ö™ùÛ¯ l5òúúzozdd¤¥_¾|ÙížµvíZ¯Ïýû÷-ýÓO? ǧuŶæc›îß¿À)M·»¨›ÝVn³~é7nxÝ´Õ™Û<Ì%úÇÒ3g»•ØFl'–­!Èa^ÛQ¾Þ…|s1˜ à/ÖÁøË>Ûê¶uXkz[â°aÃ,Ez™vÒòw §§§‡éTl?^Wijw˜bÛ¿¯˜úÏ5\ܵk—%Î;×RÔŽ`)Ù®ÞlKÌÉÉ‘ü¶D"¶ŸÛ„üµyór˜×ÖåÍã';ÌÅ`.€¿üí¨bÛУG­pæ_åÛÍ‚–@4hЛo¾)õëÝ:+LŸ b[Ζø}Åvcc£rv7•\7mlšÿÞ½{ÎSÛ€¹gìÙ³§=£]USSƒØ~®@lòe‡êÓˆsf˜>÷aÀ˜‹Á\±Æ_ĶH3Më á0¸ÚzŒ Ý³4Î<|ŸììlK¼víš»jðàÁ! }î“à';ÌÅ`.€¿üÍjb ÂšÄ6!_ëãòçë?«sg½XÖ9£¦ª_}h¶>} :lfÈ0ƒ¹þbð± Paˆm>/ò]Ô_‘=«ô|ag‹v˜*}yö,ï½!À\ æø‹u þ"0´ñ•<ß~ûíçZ>€ØFl#¶]Ô_š9½ðlnç‰vXáÙCK3§¹xßj!À\ æø‹Á_„ ŽÛˆmõm•ŽýÕŸw†h‡©¢UÝ.Þ·fÈ0ƒ¹þbð!¨#Ä6bÛÙ祫-}}þµ¼vàhG³ºªØêZ•®”gòÌÅ`.€¿üEÈQG±Ø–¥Ø³0-R§æxoåg/ÚaªVU®ªX­êVJè`.süÅ:'û5!¨£Öb±mëvl,Xhڔ¢ÖLUi»ŒÈTŶ*Oùæb0þbð™„ClÄvÇù®vëüÔ æ¶2'*åøÎöê0UŸ*ÑjSժʵt~²Ã\ æø‹Á_Äö³F||ü§Á0þüÍ›7?~¼±±1à’´´´ —ÄÅÅ~ù嗡”dþeee¡=Ÿ%˜*HÕd›‹ÈT}ªDU¥}þ!À\ æø Ûˆí>Œž={ZºA=Ì~±=è[¨ÃùÅ_ Go8pÀëvíÚµ nµµµÝ»w7uh=zyÆŽë®7nÜ3¬#€Ø&ä›U]ªÐ¨%¿ÓUfkóæ%Wo«¸XÞvâ¦êP¥¨j\5©ÊTqª>çóüC>€¹Ìðþ"¶Û½zõòŸR×qLLŒ=ÈK/½ ¶Õãíõ­Aé¡{­õ«_™ƒaÅŠAÝ `o¾ùfÀ¸ôK—.I~ÛÙ½{÷>Û:ˆmB¾³ƒ'vÇå/ˆJzëÛiH?+ŠÍª=ðÆ:LU ŠPuX½¨‚TMª¬fdÅOvæb0À_ þf5¡³‰í›7o>~ü8ô$ç .\¹r¥åbÛ¯{5<´Ø6¼òÊ+æ÷îÝ€S7nܰS³fͲÁä½{÷öçššjnFô;vì0Ýë9Õ@lòÝX)ÍAò6·/ÍœžP²2½fïQZÜŸ_kú‘Œš¤„ÒUzùÞuUÍwŽ6ä';Ì…¹0À_ þ"0¢££¥59ù‹/¾9r¤uçJâJý–––8kÍ0u>ë¬ÝWRö½÷ÞSŸpËŶ$sC¾ÃÛo¿ýöÓÄöÊ•+íÔ©S§&L˜`ÿ÷¯v¦AìvêØ±c–â‡ÖSí -­#€Øfë¯fXz; ‡c>ÙÿŽ 9³“ß]}èEÜúôgç°üÓY{*¶hÄÚìä±îµ« TªçFÈçÇ:Ì…¹þbð&G{ôè¡ÙËþE˪««ç®]»œäÖäçŠí×^{M*Cèaä†[·nÉóiªÛ&‡ëÿùùù®—Û룮{K×<ð¶[G±Ø6+9w8©*A!gAj„å솺­Ï_°¿êsÛXk¶•5¥ß¹¹pñ‚ƒ¸×kËœjßΤªÏUæÙú!À\ æ‚Í_ þ"¶ Æ S7¯:###-Ek†™Ûõë×¥{MZçää¨?Y#É—-[fnýúõSßo³çloÛ¶ÍòÑÊdþÒÊ=Ð jsçÎu˪¥§§äVUUe§Ö­[g¢Z¶õϼcãÌmÒ¤Im½Žb±íµœºƒj\_uèO£»-Ë9%¾dEæÉýß+7æƒ}^ºjIÆ4½ÿ]5®ï®Øœw*£%™òù±sa.€¿üElûû~]ÿ°Vÿæ]__ïu‹õ.$ZlK®ûc 8P醿þë¿–¤ë/mÐí¿‘k&ÐÌsKÑyKÉËËsnj/°D•±Ýž€ØFl;«º\‘q2IaÞmƒálqÆT5ÆkK …´ò %æéUè…èµèåè¼´eYm+_—]›¢Ûò{òù±sa.€¿üu@lóÍ7Þtu2[?¶Ú\î¡C‡\®eÒìò¨¨¨–ì³-Ýg»‹—̘1Ã{ÉÇ­û7Þp‰eeeæ¬ ]bFF†%&$$ ¶ÛÛˆm0³±XÑž±XÎ>M™ ÉfjHN9¶³àÌ¡Îãõ°zd=¸_/Áÿf4VmKÑÒ´{Ž\(õ^ØiC>€¹ÏÍ`.€¿ðþökBgÛn²´Ãœ9sLlÛHo»Q\\œ?ùØîYáôlõ@êW }kº¸Ïêp=g[CÁÏ;§^t‰ÿVÛÉÉÉ–¨åÓö~‹={ö8Ñ~ïÞ=óT&–¸páBÄv»b›ïµò†â¬ÚäÝG7iÊ“ðŒÚ÷V@œ‹J£&ùM‹´Iv]jÑÙ¼ÊKGÚ{t×#èAô8z(=šPðàzz!z-z9zEzQÞùæÂ\˜ á/üåwì³ÛÂBl×ÕÕÙ´]–õ/ë­ÕË›½@ÚÒ¥K-ÿ#F„ÛW¯^õoÍ­íBBk¼™gcc£¥h5õÅÎÎÎ×­‘ŽØn‹@lòÃkfÎI9¶£©™y¶íWé·9É㥸*çcEÄIJ5û*·¦ÕìÕÔ)­_Ò¦SQ‘T0O…TQU`[…úPzX=²\¯—àÏ`î³6˜ à/ü…¿ˆm æbÛ-'æÄªƒ¶Å¶S£Fj¶ØV&ÕVŒ0Ŷ [ùÌ-áæVGïéƒÇlƺôÝÎÞ~ôïßß.|ðà*¬M±MÈß4p+».ÅÚ¡5]Jë¬ú›¢ý±36sº/ù¬(v{yÜÎ#uù¾ÊøýՉЦOìÖΚ”¥%drOe>­Í0‹ÏV„Ö½*.©¾\)Ót¨D’ƒÜä¬Kt¡.W&ÊJ*[e®[èFºnª[û©ø; ô zë7Ðúǧµµ`.Ì…¹þÂ_Ä6bÛm”¥•ÀÜ***ì”ü›-¶mľ9„)¶>—¶”åË—[I´Ý—ß߭ĦíÄ-e̘1–ï÷·þü–o† ClòÛ‡id—v¹TèÕN'ÛÊÖn*\¬ÙV‹Ó§Î=𞤘 £"©`*ž ©¢ªÀ*vˆaim9ä˜ sa.€¿ð±Ø¶ÅÉ­X°½n+V¬°2äææ¶Dl4(ü}¶…­[·Ú}GŽi)Z8ݿŗƒf››ÿªU«,åÒ¥KÊÜ.qÛ‰;|õÕWo—hâ7*¬™@lò;€U]ª(>—¯†p­£E5Š,¡dåÖâe› —h8™¶]—7OcÆVæD-Ïž¹4sº–]˜©m3µ2Š‚ô'ûßUã·LÿÑ¡uJr“³.Ñ…º\™(+e¨l•¹n¡évº©n­¨ã}zC>€¹0æø Ûˆm wâV‹~[¢6¾6½*-­Ã–ˆm­¯fùûW#Ïñ ++kýúõ*ƒÒ ÚÜu°» ÌüP‡¶Û`Ì%jó0—Ïš5kÔ•-¡~ûöíÌÌL“î¶{«Õ@lò1ŒŸì0ƒ¹þbðWÈjb[xò䉉-­^_)gwX\\ÜB±m; ¥¥¥aî³­²I›óäÉ“=Ú;84Ü|$ª]âðáÃCÜBs¼Ý~ݨ°pØ„|ŒŸì0ƒ¹þbðTlÏ›7ωmƒ ‹ŒŒT¢ƒég¯v =%[ÝÅOsˆŽŽ¶ %éä·_cK6O:õòåËÛi¬{ˆ2lÚ´Ér˜?¾K´ Ã4|ÝåïZäÿ<ê ¶Ùú #䘋Á\1øË@w-ú­ÞþÕ«WK£ž?^=Þà5ÚöÝiiik×®Õ¿/^l»uÛˆmŒ`.süÅà/³Êu„ØFlc!¿]æb0þbð ä¨#€ØFlc„|s1˜ à/rÔ@l#¶1ŒoàÇ:süÅào¿& ä@Û¨#€ØFlc„|s1˜ à/Æ>Û”PGˆmB>†ñ“æb0À_ þ"¶A›¬#€Ø&äc„|s1˜ à/†Ø¦„€:BlB>ÆOv˜‹Á\1ø‹ØÔQûb›òÌÅ`.€¿b!‡ˆmB>†ñ“æb0À_ þ YM@ȶQG±MÈÇùæb0À_ þ"äu„Øfë¯`»2wŽ™ðÖÄéípãî :œ1oFÛ)!!À\˜ süÅà/BŽ:ˆmÄv;³yËæê%ÿËý/ípÂïÆë°çëÙ`.sá/ü…¿!GÄ6b›OÈ0æÂ\1ø‹Ôb±MÈÇÚlÈ0ƒ¹ðþÂ_€£Žb±]rª8µ8õhÑæSu©2ëhfáÉ‚ït«¾\Nȯ¼P‘Qž^u±²…Ñ㤗¥•Ÿ+ûNÏ¢ºÂp2,;SZpòpóÞLéé=ËwºÉ'÷X®^!Ÿë0æø áoKЯ ¹gŠ'Ož\¸páÊ•+á8ߺuëÎ;ˆm€Øî,b[¡4bFÄùÑÑcþì¿ÿÙºmkÃßþÝßôèÙã'?û{ÿµ~>@§~ñË_ØážœÝýÚß2±þú›¯ûCéÜØ¹}û÷ý“ò'²~ÿ»ßÇ‹¢”4ä(H–§Ëð¯þÇ_íÎÞæs­ÜºB9¸kõ€zLýÎpÛ°s½Æ ðCmÚ³Ñë0kÁL=ãÐß Õï•Vn?êñ£ð߉ì`Iê ×þ§ÿîOu­=ò'‹?ö^’x0Q—¨´GΗÿæÿgέ>ÄOv~¬Ã\˜ à/ü…¿ì³ÝfQSSóÒK/uéÒÅž¢k×®ï½÷Þ—_~éõ5jT¯^½6nÜXXXسgO¹?± Û"ä×õù_}^†‘cGšÏ¯FüÒRR x¯U<¶ôI} Ã½‡öͧÛî–"Ï.Q›ñè÷Gù}ký!ߤßyù–åßù\s–Î Z˜€ =.r\P·ßÇüÞùŒô®Rþâ/ÿBQÙÎ*ä‡ùNd*mЧ2lHEÃQóY¿#Î-[~²Ã\˜ sü…¿ð±ÝƱk×®|0É][[ëÜúöí«ÄaÆÙYÄ6@lw¢ÿÎïü!À¿û úRûn|òV…7KTÛ³|>Û·Å'ÏœdWf5<ëðï~ò?-loÞ³IƒÇ44ÎZÍ5QÛ%K7,qQsMÂjÅË…kc,ÞûC¾á×oý:)?)óHæ¬èY–¢†ê²³¡§)”š§ZÁµµ‰:46Lh‰ûr÷ºxç¶--Q>z^õ-X¢ëa°oPøûSÞ_·8Ìw’S™í~÷¬Š_©[¨)]Mï–¨—òí%Œzo”VuÁOv˜ sa.€¿ðþ"¶Û ®_¿nÚ’Ö999wïÞÕHòeË–Ùãhè¾Æ–{ŶaðàÁ‹-*((@lÄvÇù KöV5äÌ›®™Q Qá¬Qܽn ÛJT¤·CkEþí¸ßz}”³ B³|”¡Å?Í¡r>ɇ÷?-ä™8Æ››Æ€ùÛ¿ý¶+k—¹)¨{'ªÙS(fÛÏ¿÷ç?þs›“æžÝF½üêË!à 6­.üwòËáoX/^µ·$ðfÏkÉ\ÈWž‡ªrX¦æÂ\˜ à/ü…¿ˆí¶Œˆˆ+y}}½7=66ÖÒ“’’Ävttt'±MÈŸ¿âÓ€&ggoþöÿÚ) rï}øž¦•t“Ä,eñºE–â¤)€)ª¹¦n5´kiý?)oŸ]µ0*àvÖäìùº6`Í…Okt·9oÊÙkÖ&íF”õþÛÞº©»\­òÊЖlÙž¶Í|ÔÌP˜ác†»g÷†üÌ#Î'œw¢Ÿv¨ñ{·ˆÝ¸ÔNmÙ»Ùò篜Ϛ¨0æÂ\á/üEl·qtëÖMÅ:th@º–Iû颢¼b»Gˆm€ØîD!Üä±Þ@´%[Ét˜Z”b‡S?™âmuVvËŽ™ð–wDÖkC_UÓð- <¦9f·›6wš?ä«­Ú_0[µE+¸•T\C¾L­æ.Q3¾´ö‰B»ýò0‹YmgUN…d¯il›Òè>{Rÿ[ ç¸î ep kwô«ËB¾›‡ÆOöÖÌ…¹0À_ø ³š€k]Ü¿ߊç?«å:õæ›ozÅöˆ#:—ˆmBþà7û‡c™­M\c/\S¤,åÇýc[­Äm(ׯGóŽÑR“³IˮȒÃô¹Ó-åpM~Àí­]èù.~û[âÑmmÕ§…|m¢ÕMƒ®=cãÇÆO}_‡¡amóÈ5òÍ_˜ÐïDmçßy Íó†|dã';Ì…¹0À_ø Û2ruuuVìÔÔTÿÙ>}úèÔ€¼b[«”SG s‰m¶þ²VÞ ÍØZ}ÄÔ hq׊)n$˜V7 ¸PMËú¹ …F¼›èÿÙåÉ!#à*E>È× ®7·ÌOÿá§ú¿ö&UÔ÷šníuÖo µ£k¡Q› fP[»N©QÜu/- Ô4ò-tÈýN,Å&¡=íwGÈo/€¹0æø á/BNhhh°bkAò€S=²SÚñ ± ÛZl»¸®8íß²ÒNYk´¬°¶ÐRÔL®ˆî~+¸LávfìXF Þv•†~i­Ô€åFÙ‚¥þ™cÞág6UL>AçbÜW…±hêLessÛ¼#ëwû¡ Ëµ˜ª†ù¡ß‰;ûêÿyÅ%º)pº…L“Ùùí0æÂ\á/üEÈ ?¶bÏ;7àTEE…š3gb ¶;µØvaO-ÓÞt…yIó'ôúÏmì–5WÛŒ)³ »6xgš9su|ž’ í+]{³×Gë£Úíü!ö’Ù^OÍþr‹†3#έ­ÒÕ6ïÆÚ\®iiãC‡üÐïÄÌõt¶ìª³ÈßGº}Jùí0æÂ\á/ü5 äz÷î­bwïÞ=`Ù³+þÀñÜÜ\Äv;b›ÏëÓ”ñú³^ÖPÜìÀ 8¤%L,&%ˆwÀÔlO­P4âúã“fjY¢f£Yk½å?âíÞ–ò¡¿j‡¿›=Õ­Sª b·OíÀiñrwö.9¸¡q!žKûjÚµ3æÍp‰Eu… Ìž½“Єe›b]'NŸh‰‘³&‡ù¡ß‰´ÛÛoëź_Zzán±™Vùú$ôaèóÐG`.Ì…¹þÂ_øÛê@Èi¹•|äÈ‘>´ÄòòrÛ|[[‡ˆív Ä6Ÿ×º¼9úËžS—Ú’ð°q÷ïü.­ÞiÑÈß níît…ŸüìïÎjŸO¥ÛŒ/ÍìêÿÓþ–•<óÑ©.ýGí÷æ´}Ý`g½S¿Tæïü)ãÖDÕoý ÑN$îr7»,§2ÛîkƒÐ´Úª+›Ö_ÑÆùa¾…ywk¹éº‘{(Í7{!_Ÿ„> }úHÌ…¹0·3þÂ_øÛ¯ ¹VÇ“'Oh…—ÀÖrh½zõr‡ÅÅňíö Ä6Ÿ×î#qúËžTõy #„–±Å<½˜8mBÐ6l­)Ð&íL-èÖš€1ÇhÏOï´.kçvøÙ/^R#º7ä[#·"è‡Qº¨ln”ЖQžn º8Øån;MõÜt»f| g 禄…ÿNÌ´©û1ä •côüCm¿–š> }ú<žÿ7 `.Ì…¹ðþÂ_dR'r<ˆŒŒ øÒ$¹µVy@{‡Ò'L˜€Øˆíö„ÂSéú˾2'ªåABÄÚsÁªZ³D1Õ^óL±Vã»f-˜©eNÕ’­˜ªD«³ööÐtµå[–‡nQ¶Æòă‰Ú¡DˮدðmOÎn…áis~§{i‘MQ ê¦u_åµ0JÃÌ NVJ«[þ‰¼¸íëôN–¬_¬IkJyv¦OB†>NN˜ sa.€¿ðþ"¶Ÿ5®_¿®ÌW¯^œœ|þüyõx#;Û ññ#›<–ýíx6 ÓÇ`ÓÆôytfvÀ\ æø‹Á_Ävó¨#Ä6Ȭ٭¿ïqùó u˜™>}ú0`ÌÅ`.€¿üEl7€:Blƒ¯îÝš“s1˜ à/r€:j ¶ù¼â‹cõç~vò»™'÷w¶h‡©ÒUõúôø> s1˜ à/r€:Bl#¶[¼ù§,åøÎÎí0U·*íyÛ`.sá/BÎ:ˆív€”êû뿹pqù…’Žê0U±*Új\Uÿ¬¾*s1˜ à/ù¥MÄ6ŸWNm’Å€9Æí«Œï¨ÑS媊­®UéÏð“0ƒ¹þbðWà—6uÛ|^×¾ºøyñ2 +s¢rëÓ;V´cE–tU«Õ¯*ZÕâc™¹Ìðƒ¿ýš€kƒ¸}ûö—_~ùnwïÞ½råŠþ 'ÏÆÆÆË—/_»v:Bl#¶Ÿ-* ¥EZ`H(YYu¹¢½‡:¬êr¥ªÒêT•«*ãC…¹Ìðƒ¿ì³}çνM¸uëÛù|РAz¢„„à nÞ¼9eÊ”.]ºØƒë?¯¼òʹsçÜ=z´zõêîÝ»ËÇЧOŸäääзž5kÖw¾Ï… ÊáwÞiQÄ6xôøaê±D‹ ~rlGûv˜ªO•hµ©jUåzëÀ\ æø‹Á_ÄvMMeXXøÃ´Œœ={Ö °uëVÿÙ7nôèÑã$¹?îÜ?~nÜ8K×x ßµkWj²ý½{÷œÛöíÛÍ-33Ó_†7ÞxÃ{÷€³¦± ˆígÄ68q¹<¡x™'ŠünOÅ–£ËÚNœÃTªU«&U™*®s~±æÂ\1ø‹Ø~òäÉ€$>%¡5ŽZý½v•$ntt´];I©wªW¯^UUUn ôÌ™3½}¿ÊMã®ÃÏßAÝ×ÚP__ï¼ù‡Ûv*`]4 Û 2ס:±Í-+++ ç\²\nEEE9¯_¿Þ:½'Nœô}ª¿±ýœ€Ø7¿¹–U³Û-â•ôÖ¦ÂÅ9u ·?¬© 6,VuX½,L›¬jºñÍÕæÕ2€¹Ìðƒ¿YMèbÛÜü¢Ñ`kŒ´ÜüÝ˃më~÷íÛ×Rüáço°ßîZÃÅo‘ŸŸÿ4±ýâ‹/*}Ô¨Q.%@Æ4Â\njP©œ[8#çµ$[lllÐ÷ùÅ_¸ªÛ±ý<€ØÇ.•n-ZêÚq—fNO,[“]—ú<㦮׮—ï*bkÑ’cKø>Ì…¹þbðáİëmÞ¶m›Dczzºº£-qóæÍ¶8YRR’¥ÄÇÇK…Úpq Û¶Du «¯[sžm ´©ë0ó-¶Μ9ãÛ6.ÝÒ¥‡Õ7®Nx½Ràêr÷Növ×^{­¶¶vĈ¶ šþ9r¤Ð?QÜ4¼zÚuèÛ~HÆ#¶ŸÛ|^׿¾œqbgÌÁI.äÌN»6oÞÞÊ­…gsŸEÃôbõzõ’õªÝk9øAúñªŽ ÕÌ…¹þbð±]RRâ_LÂõis¶\µ·‹8**ÊÒµ1uøùÛ íÚ&Hè†/¶¥ÞÝðõ|Pþ§OŸ6OS×oÍØ·oŸ7ÛÉ“'[7¸zïÛˆmÄv›FíÕJíl±2{–E ³˜´É[ŠbžØsôb9¡º%¦¨×¨—©Wê}ër~ðXbÝÕªUÌ…¹þbð±=dÈ »F š8TlKôZJZZš÷«W¯k‚¦L‡›¿á‹mÝÅÒ ³gÏÖŒq)gÛâ˶ÑÖÄry:m’8½ }ô‘Û$LºÝòÔY¢M>Gl#¶Ûí·ï~Q~.wGÙš©½Áiyö¬íåq‡êÓÂs˜^—^š^÷M.HØY¶æÈù¼Ûwo„S#À\˜ à/ÛÒœ§RSS]´_l{{°¥Q[ž³Åvii©¥»²¹[»…Ä-ݹim6oË—/·ôùóç[c DŸ1c†ÛˆmÄv;Ý,ôÔ¡Úý¶_¨³¨¤1Z´S»˜h#ÊÌ“Ée Å„v3½ŠÌÚäÝG7éåèéEyß›^£^æ…›&Ì…¹À_ø.Ûþ¹ÓãÆ­ãÚ/¶5íÙ:„[žKÄö¹sç,]³µ.Ùµk—Ò¢â&†­ÀÞUÙL]››žH‡ê“wSÇ˾…[ðܵ.b»}±MõßtOÛ`$Wm]–5ÝÅ0gŸ¦LXuèã„’•ŽmÏ?U}¹ª3x=¦V¬×ãë%øßŒ^—^Ú‰ËG<ºÇW`.ÌþÂßç‰~Mè0bÛä¨Õvª®®.¨Ø–ª´M±nyþÍÛ>´ô)S¦\¢ÀìÔ¬Y³tØ¿ý¿wïÞvÖ¿ž¹VPs먅ÆÊ•+ÛíˆmðàÑ}µ»—ÍQ0Û?ÿÓ”ñþP·8cê†Ã1»ŽnL«Ù›w*£´¡¨½x=‚D£‡Ò£éýO­W±áðüUñeçé=ltÖ€¹0ø ùÛ"±­žÛ€Sê‹¶SR³AÅö‚ ,E›rYŠ[8mpª««ÃÏ¿ÙbÛ©\-*n‡þ.këW—ƒ­yfgýÛe[|ÞÍ7ßÛUÄ6b›jî¸uçúÉ+G5Rk{ÙêåY3ü±Ðl~êDí´±6oîgE±;ެO®NÔX¸‚39G.”µ… ®b¨0*’ ¦â©*ª ¬b?í‰ô°ÛËVéÁõøz Ïèõsa.ðþ"¶¥6ïÝ»çïìÕ ÞþÕÈV›3gŽ÷ &XºV?ÿ–ˆíáÃ‡Ûøð7nŒ]^^®Cõ®ÛaNNŽ×­¢¢ÂÒ—.]ú´»¯[·Ž9ÛŸ­ˆmð¨ñá…[§µÖKJuBBqìšCÛ'!ì“ýïh±P-g²>Á–¢¥ñ%+K×ì(Óä4íÕ±¿:1åØŽ´{2NîÏ®KÉ­O?|:[Ûx”œ/(¿PRq±¼úr¥LÿÑ¡uJr“³.Ñb¤º|õçÊJ*[e®[èFºnª[«¡K¨GЃèqôPz4=àÃÆÔ5€¹0ø ŸÛÖ¯{çÎ%jíî‰'Z¢DfÀÔh-æ®ÕlS¹ÅÅÅ–¨yÎæ¦´ÃÏß°eË–^M¨¬¬ü^b»¾¾ÞN 8P½Ù–(E­‚Y¢¥è¾ÒöÖ;mò[8þ¼îhO¡ÖÄv `+b<~òXK€^¸yêÄ¥òâ3™Úbt÷‘¸Í —g}4/å}ÅÔÜT FERÁT<REÕ˜4[…§Ì…¹ü°€¿±mP‡³iTÛ@[bÒt©‰U7ïÚú¨MµšƒfbßücbbÜÊdá‹môiÓì¬õ¢wïÞÝ•D}òÎ-99Ù[`yºÃøøx9 ¶a+bû{ƒÙh_|såÌ5• KÎfœJË­KΪÙvl›æ§í=ºqgùÚÄ’[‹–l<½.oŽ6ÉÔ (‹Ó?ŒN˜{ནޖé?ÚÛC‰Ë2§ËAn›Gë]¨Ë•ɪ­iÇ·gÕìQæºEéÙlÝN7ýâë+,£ÌmËþĶv½Ò~Ô/x ©Ë×®]ó:/Y²DéN»m®½’Õ–Óv\ÍÈÑ¢E#Õ}«Ž‡RÅJw2Þ ;êª7­%nýÛ]»þvŽãø-vÆn¢ d'! 6˜˜ðü> |+=èaùçüÏØfŒ]Ü#@lÀóã±MÛZÓZcv?„÷ÞcŒ¥º‘þªµZk½÷9ç“ù1BBçÜï"ÉZ+¥$¥TJ½sNټػ# W–(ÃÇeâ’¸¤]6$.½.ã]›uɺ¬S;µS¿ª‡¯nÕ;7›d¿Ïkdó§»O¿&±ÝZë½àGc;CÂó½#Äv‚···ˆHûSÛb±]kˆZëHˆm±Øžç9"Îçóø! ¶?>>F‚„ç{Gˆí´ÁQJ€óŽø±í›Íæp8¹‡&¶ÛûUkmÀ=$ìÍÜï÷B.‡DlµÖ§˜:O‚ØJ)±,‹ØN€ Û@k-"¦i)± ,Ë2MÓñxY± ôÞŸf¸/ ¶[k—Ëåv» Û‰CÓ®+±Ý{Ÿ¦)"¾¿¿ˆm‹Û‰Ûù‹Ûurn·[)%ó3Û÷_ÜžçyÀÃØívQk)±}Ùg¶ aAh»ÝŽÿ ÛÀº«œ=䀨J)q>ŸG @l×ëu¿ß÷ÞG@l?†eY®×ë±¢µ«eYˆíÄÁ›ÍƈrÄvšãñx·Þ€ïÕxx€ØNèíû\l€qh›Ukm<<@l'ôö߾إ«ãñ82bû÷€ÞûétŠU­u$Äö¯€sÚ1MÓsÝ; ˆí|ó<¿¿¿HÚCþ\sѱ¯÷«RŠ³Üˆí·Ûm»ÝÆêp8HnþüKòr¹ŒWˆí|µÖišþdb$|~~‡X½Òj ¶óõÞk­Øðßv»]¬¦iªµöÞðêÄv¾óù|¹\¾¾¾ÆˆíˆØn·ó<ÿªÌÄvþµ•RN§ÓàEµÖ¾þaï4‰â8Žÿ‚ ˆ!„HôU%AƒD!@„^"¨Qz  ú/ÇZ7ÕÞÍ®åÎý~|¡üÌq&˜Ïçý~ß{ÿ|ÃsãÛÿ^ÇÞûR©¤À9÷ôkŠU«ÕÇË3¾hCCCCs»Ýž6<ŸËå2N“ýÛihhr¹œcû?\8Çñ·ú³¡¡¡¡9’Êå²>àù\¯×J¥"i<'éwÑÐÐ8çª÷~µZñcþʯ,÷'ñsl×j5ýÍf£`4YÂÆöû X,*˜L&vûý^R½^7<Øn· †Ã¡€DclÀ{ …‚‚Ùlfxö-YIFÃðâÍE’ƒ€äblÀòù¼‚ÅbaxqO¤¤f³i/àx<¦R)I½^Ï@B1¶àO9ç,—K{»ÝNR«Õ²×p:Òé´¤n·k Ûï€l6+)Š¢õzmŸal·Ûmû-œÏçL&#©ÓéXâÆöç€ìÝG4AÇñŸÝ]+¬X6« X( …‚…… õæH¨ (@*”JY()Ôq‡»ãóKž©£žñ|?/a‡±_fþdY&Éó¼ c`6±³³³4M»âˆíá@·Û­sÈ÷ý­­-ó7Øßß—´ººj,àââb||\RY–ý~߸ Û`¡Ñh$I")‚ACXØÛÛûÒÑh\__×㊢èt:¸ŠØ ÏÏÏõ•Ú0  ììîîJZ[[3°v{{›ç¹¤åååV«e€{ˆm°ðððDZ¤(ŠŽ ¬íììHZ__7øŠªª¦¦¦$-..¾¿¿àb€ŽõÖÏ2ŒŒœžžÛ?âññqffFÒüüüëë«Î ¶X`@ô ±% zûêêÊ|—ð_2Ãyyy™››“4;;;hoã,@l€“““(Š$Åq|o† Ûßòöö¶°° izzºª*ã @l€£££0 %ŽŽ>==™û~|Å›ÍæÒÒ’¤<ÏïîîŒs±]€ƒƒƒ $%IR§"¶ñ‹+Þn·‹¢499yssÃç€ØægÔ=¶··}ß—”¦éÇCÇÄ6~wÅ{½^Y–’&&&.//C± ›››žçIʲìÙ^AlXYY‘466v~~n€ˆmØ»ˆfÂ8Žãÿ„Â"Á†$Bƒ•È„Jl•¤@)¨„JB‰P‚Ä4”DEUÝž÷ï?÷X{vWÆ{&¿ö¾·]<ùöîB¡PnxÀòzuuµ²²‹Å,Ëâ| ‡Ãñx|}}ݼD|kk+!žŸŸ•‡óóó„8;;Syööö¢ÑhKK ‚ÔÙÙ9==ýòò¢¾»¸¸H’É$ï¨çûre³YeH§Ó‰bùÞr¿|ZÕíímÂÃÚÚpmÛV%áÓ˜¼=áÏÄ6ëèè ¢ÊÊÊ““Uæ± À š+íššš–×ÙÙYòÀ7?ßÙÙQy&''I¬®®*\Ñ$R©”¾‘u[[yXZZ*øCyãÄ3õÝÆÆùùüüT¾Žé'½½½ooo%ÜLžÄÃÃÃ_ŠmÖÕÕEDGGGªlb`jjŠDmmíÿ^^¹?ÈÅ3ç¡¡¡¹¹¹¾¾>˲È566öõõ¥D&“!Áñ¬Šy}}%Q]]í8Žííí$ù .//OLLD"ríï͟¡ÙÅgƒòô÷÷¿¿¿›±Íø5—9¹ø›þ2¶ùXÍy þŸÖÖÖĶÖÓÓCDühºƒƒU†± ÀYK¢®®.€åuxx˜DUU•9™ä31cŽÍñIâññQiF÷rN¤f<×ù³»»«ûÖŒíëë낌ç÷ëî7zyyinJço—‰ëá¶lóQ”!“Éð…„¾J±F‰( É©€r‚Øà%Q__ÀòÊá§7fó뇽ºTu„ó€Úg¹Nåd2I¢èìîînü gŸØÖnnnxfN‚Ÿ…æÛf½Ÿžž–Û,•J‘˜™™QÅØ¶mö¼Ûæ^€ûû{ýKæ8ÎÝݾ>àßh±XŒÄöö¶€2Ø$ÑÐÐÌò:::Jb~~^ÌxÞÜÜTâéé‰D8öÚCÞÔÔdf˜ìE/txxh‰t:ý½3ð°* ÃxÿL¡"PBE4T&M‰!‰””ŠÔ(ÕUPI´‘TP¤ Š)‘Tßþìcwï·s:{gº÷îz~àöÍwÏ9çÜœãwÞ÷}¿fÙ6žpàÀ6²}õêUýélûÄÇÆÆ<o޼ᕯôæ‚ v'4È6Ÿ÷ìÙ£¨»_²ÃOz¼Ó³¹,uº>¬ZµŠ?mÞ¼Yÿ|öìÙêÕ«½¶ÉŸ>þÜç'Úèè¨öuíÚµB!„Ù!j¤uÛY²dIßn¯¨äPç†Öâúʾ}ûjw£ï.é={ö¬H Ž7W;·”m+=ÎÙ ÛŽ÷®[·N}ÿþýldûéÓ§šÀî:[¬;³ÝÀÈȈO¶–mÂøºþ5mWõ>™ð¥ÎQãt¶S'ùz#JF òßç'5ÿÚ­ìË !„Bd;„6mÚähpßn¯, å¦h¥‘¯_¿j&}§=H‹òZªÁŽæÕr(·'ÐM¨™Õ°z–mPÿ6W¶[¶¯\¹‚š ä™M!ä]5ä½É6 ƒÉײµ5È»›íôô4Eì¼› c¹«Êg’íãÇû~ùò…‹|ÿþ}Z¯iP¹{Ñy;†x¾Æß½{§(·¢Ù$Éÿþ­MNNjÂÄÄ„ñþWC°˜\!„Bˆl‡‚+–—-[ÖÏÛ«-‘ÖVåg rj$î‚á çâ‡uÀ™Þ㤠ϫ`³ìBhÌÿßʶ;™SêlÙn€ë\ l“¹=Úé^èÀšÛ]ò\ ë·béZ€šÔáÕ²½~ýzGæÍƒܛݽèê¾ôêÓæ~ýd¤—H#gpÅŠy¢‘Q½‹é!„Bˆl‡‚Ó›—/_ÞçÛëóçϽ¬WùT#×wèÚ3m¼SSSÿ&$‹±3Á¸VùÑ£GíeÛéµlK}…Gü ÀeÌ=¯³½råJíœ@z¼FÌÍ›7½Òx-ÛÊHgPlƒck©éAV5Â|—gw9?J/±gƒnöN»æƒz¢‘G ýòk–¾B!„Èv!¬Y³ÆqÔþß^1±–‘múuiæÆ=,¥ñÓ§O;‡¼Mø§OŸnß¾ŒY¼åŠJŠnÙÖ·šk¶Éë&=› °—ÚnÙf¦áy©mðïÅ[7Šÿ;î wùòåZ¶ ÃÏŸ?¿k×.^(1¾K¶?|øÐ•ðàA7ow¹+Y€\zN|àO´C‡i×äÌ—>B!„Èv!¸iÈíÕQ4²4òâÅ‹®Öߎë’Þìªoç7 m½x5±b}ñèÑ£-e›°­Ô]omC,ÚbÏçÞj¶I¼÷:Û¶Wk†eÒjنׯ_[È}Þ² ´wuºÛÚ‘…Þ™µŽû»†w¬(6Ø'¿©ö~äÈ‘òK !„Bd;„h]»vío¯ôê3 Þef(îZú˸]6Aië.…Ç¥ô"f ·nÝšimjwán)Û¸¨;‡5˶ñ:gXnÏÝÈO:¥ wîÜáŸô`ã³Ô÷·@ËkÙ¦™œYEï‡æŒ8Yݵl»Ür'ÿ{‚a›ä ìÝ»wñâÅöm>;×½ ˆ'NèøßR~!„Bˆl‡råæÞƒ½½ºxûöíeÈ6WÈ”²m¯ÿl^¾|éº\åëîêvæˆ7Üæšp¶ÐR¶½¦4ºÛR¶Ù¸WÿêY¶ïÞ½« 4c×ò]ú'äuî=Çß¾}«e›¶áu~µñª]ÚÝà _ã« €³}_^öòäÉÏW~»ß¤¼zõjàO4 t û÷ï/sK!„"Û!„àæÒ°aÆß^6ܸaUdL›údM¸páBÑäl!,Ú Yëµèªã—3ÛÈ6q`WJh”mG×õW¬~6ël{Éq–.ókÙï?JX´»ÇÕ²}éÒ%·=«“®-Û†2lµ‘>ŒÕþÏ9z¨T×8ç†á‰F:}ÕLn.!„Bd;„–.]ª{ Ë2 ÉíÕŽ [·n}øð!‘RƱb²¾]çŒQS&] âܹsL0ĺK=ÀܾëÞ½{Þ¶OŽ´Jǽ[¶Ýpû÷¿À?—Û»pº–mއɆq'û•Aϲmiw‡m6è¦îÔN»©8úí‚üZ¶½£;vè[´”sø®_¿îúëæñãÇ-ÖܾŽLr bþ4]Ó¸ãeÐ\¼xQG²{÷î2'„B!²B‹-rÿ°¡º½¤•ÎÄÈÈ*ØÐZœ9vòæEÎ %܆‹‰‰‰zé¯K;Aæb,Ûœ~üH‹rNêÆ-OŠ,zŒ Îbsg²׊×/ ØQŠ·oß’ùO‚Ç@[r*Ú'ÚÔÔ”“&J!„"Û!„ÐóçÏŸ÷'dÿon¯°w­…qÇmmŽÌ2K%Š„â*‚BÁ $B¯$õ1À3ƒ¤À”ÁÆ­Xª’¨66ÅsKËVÝÎåìûÁ ?øžÚùÁ}ñx\Òúúº7.~ppà÷û%­­­@lÀ§ŒŽŽªikkË|±ûûû§§§WyÛ‰/Ï\<›Í:Ž#iuuÕ´ Û0<<,©«««¹¥üÄ6ì¼™Þ% ]üðð0KZYY1€Ø€–†††ÞJ{ww×|±Ml/--U*ï]üää$¶x”ˆm°[P’|>_2™4ß@l£V«]__Ûm_<—Ë JZ^^þË6 ¶àùù¹¯¯O’ßïO¥R¦ Ä6¸x>ŸûÚÅââb£Ñ0€Ø€år9‰H étšôo_¡P°»îo»ëÕjÕb¬R©ÔÛÛ+) Ú¹cÒ \ü³ÎÏÏÇÇÇ%ÍÍÍ5gÞ;Ä6‹ÅP($Éqœ££#Ò \üË­b±˜¤™™™r¹l:Ä6œžžöôôH²Ÿ¹\Žôúi———ÛÛÛ;;;õzÝx¿½½šš’d?ïîîL€Ø€ããcÇq$…B¡B¡@zýs777™Lfß¼K§Ójrù?í^º¤ÍÍMbÛ…×LOOKŠÅbWWW¦£@l@6› ƒ’Âáp©T"½~ÂÞÞžšþol7ÉÉIIĶ ìqggg%MLL\\\Ð!± ™L&HŠD"Æ-ÄvµZýÝäÎ&óëëëÙÙY"‘El»;¤7??/ill¬X,@lð¼T*ÕÝÝ-)>>>÷Û­µy‘Z­ÖòoãmÛî«×ë ’FFFòù¼Ä6K&“>ŸORÿËË éõC*•J<·¿d5ÙŸýaï ã8Žÿ_‚”"d’@DÁ(”ˆ pJ ŒK PE¨$H‡Rž›gÞ³÷zïÞƒ»V~2øÚö{Ƙ¢(ápøþ4fY–#‘ˆÅbÑnM:žÍfL§Óé¨) ‡Ã!‹‘×ëe¤þ±ýX·Û-‘Íf㄀؀WÔn·ßÞÞˆÈn·³ é¥&1ÝùÝ7ÛµZ>ÓívÙ»J¥BD¡PHMn⾌íÓétxdz±ýÚ+V«UQˆmx1­VK+m§Ó‰ƒ þÃ#ÍÕj¥²Jý½^¯?mI’ˆEq>ŸGY–q“ÉDÛ¿ß_¯×ƒûk‡±ý@‰DB#œN§ Ûð2šÍ&q.—‹ÖÈ/—‹ D ¯×«~ÎZËãd2ùKlÇãñóùÌ8ÄöI¥RDd6›Çã1{ˆm€jµJœÛífF‚Ø^,ÄF#öQ±X$NMk}lï÷{¦óýbÛ°2™ ™L&I’ ¶à©•Ëeâ<3Äv¯×#.›Í~ûHEâv»ÛÚvÓÙn·t‡ïÞ!¶ *—Ë7 ¶àI•J%â|>3Äv£Ñ ¯,—ËŸ±-ÓÙl6ˆí§“Ïç‰ë÷û à ü`ï<"‰£Ž¿ `þŠ…D’‘P¥’ˆˆ(¤"%‘H i0"¡è–é¯H€ ‘€ôn½uÓe¯ƒs»¿™ý~€x<¾v¼ŸS€Øà€……1ê$b;Š"1{{{?¾ñúúú]l¿½½•ª|||ÛŽ[^^DZb@Ž”³JLww·ºŠØÎN‘—£Z¿z~~¾¹¹¹»»SSÛHË·ÕÕU1ggg ˆí\0;;+¦··WFl?<Ök}Åq,æööö±]¨6I’¨yÏžj ÃP ±]H[[[bŽŽŽÛÎ099)f``€õZwÙ×Ù!ñêØNÓÔó<1mmmCCCåÿãû~víŒØ.ª1Q) ¶`llLÌðð0ëÕòKùÏ$Iļ¼¼¨©ôöÈȈüÆó¼ýýýÊ£ÙÙcé•ÿ—Ø‚€‰;(ûáàà@± À)ƒƒƒbÆÇÇY¯NIÓôþþþééIÿêññ1I’“““«««ìwoˆÑ¢ Ã0»K¯€Øàˆþþ~1SSS¬W0ñ<:<<³½½­€ØPw¾ï‹™™™a½"¿˜øññ±˜ÍÍMÄvèéé377ÇzÍ;0ñÓÓS1ëëë ˆmuÑÕÕ%&Ö+˜x1”J%1+++ ˆm5ÖÑÑ!fii‰õ &^$çççbÛj¦½½]ÌÚÚëL¼x...>¿[Ä6€hmm-ü%ö˜øååeSS“ˆÌÏÏ+ ¶üW---bvwwµñHC‚6ªëëëææŸìÝD«}ÇqÛV“šj,c±‘†…BÁ`0( ƒ@UUUBÕªj H@” ¡¨¡¤`Ê ¤PR¨a¸ÞË™÷qœ§Ždø?€»ßE_ënÅú¢Ñ¨bÀÄçóå|~~^ŒAlC vxxXZZª¡««KŒ±]xª««õ´-K<F_ÎןþÌÌŒÀI<—¯íííº“ÊÊÊããc1€Ø&¶Äb±|iû|>ùÐÛÛ«;I$òW@gg§N¥¬¬,™LŠÄ6± `zz:­555òW@OOÏ7cˆF£º‡Ãqpp FÛÄ6€©©©ü©ùÛkkkò @ww·ÆjµîîîŠ!Ä6± `rr2§Á`PþÇÞ`,EQÿv"‘H$$"T•¦$‰D"‘HUSUA[¼ßãn ™7xÃÿ·†{‡yæÀp84s<r3Æ÷ûÇØ¶`4iH‰„ü æfN§“þg|>qŒm–ÉdR€Ÿõû}s6çóY€ Æã±vÎûý\ÇØ`ñŠÒH§Óáyc–ïV‡à"Æ6 FC³™Íf%0¶/—‹Ìf³?週m@­VÓ`æóy èõzæ~|ß—P€Åb¡-´ßïÅ Œm7¨T*šÊb±(À„ëõ*a«ÕJ»h»ÝŠC`l T*i$Ë岄t»]sE·ÛM,›ÍFi½^KìÀØ  …‚æ±Z­ `¡ÓéD2¶Ýn§½´\.€¸al €\.§a¬×ëD1¶ï÷»Ö‡ƒ¶Ó|>b„± “Éh›Í¦ÖÚív„¿n|ß׎šN§@,0¶¤R)¡çy Õj™‹z>ŸàõziSM&“öës•8Šã¨‚ D!´”@ª)‚  j ‚ кîû1[hÞpξ÷ò ¨8± ‡Ãâ7›Mü,‹4ªTGñ;çyñ¯¶Ûm@e‰m`0¸Ûíâw`>Ÿ§]].—ø)x<Å×Z¯×$¶~¿_\ß~¿Ÿ‚,ËJŠmx>ŸÅïZ­V•"¶^¯WœÞáp('¶¯×k”^¯W½^O[.—!¶n·[ÜÝñx (Ál6K»Ýnåx¿ßF#Í,˲€?'¶N§“.®V«N§(L§Ó4³ûý¥ÏçÓl6ÓÒÆãqü!Û@»Ý.Jû|>Gi`2™¤¥åye‚ï÷ÛjµÒØF£Qü ¶ìÝÂ`ÅqJ3™QƒB¡ ªê «  €Š !X!ø Pêv¢¾àÿà ÀuÎ`¯×+—Ëi×b±Ø¯ÿ~ ;cØl6ù|^óÖjµÞï·` cÀý~Ïf³Z´x<>°2¶‡Ã!§€ûý¾P(häšÍæóù,`l0Æd2mY"‘˜Ïçôû}_v`Íáp(‹šºF£ñx<ä§`l8ŸÏétZ+æ8Îb±ÀŠ^¯§©ÇØr<}ß×àÕëõÛí&?c@†žçi¿\×]­VØÒív5x“ÉD‹¢( ‚@³W­V1À×1¶ìv»d2©åÒçv»À¢N§ÃØÆ_\.—R©¤ñ+—Ëú.|cÀz½v]W›åy^†üclO§S¬3ÆT*M`§ÓI`løŠåré8ŽÖ*•JEQ$€uív[8›Íø‡ëõZ«Õ4„¾ÿaïaâ†8×À‹žœ@€­7Å›zLô%= †sÈ"ö¼¡àÁb°Rðâ­¹3,°@7`{Ü÷‰e$/Sü®û_Ú»···Œíõ}yy9›ÍöööòäfKå:ã̈rõ»¿¿ïwÆýÆv¬666²,«ªªmÛ®ë¼nï[óÀúyãyHå‚rõ úŒí±²,KÓôúú:ÀZjšfssó” ÊÕ/è0¶Gé—¬«¢(’¥ß(Ð/`lŸrÕ_Ÿ»Ú@¹€~àcû>Ž¢®ë¼vÕñeäå‚rõ úMcû­>µªª¼0â)ÊÈËåêôëþSX1¶?@UU«¯ôÿº(Ð/ cû…®ë’%¶Êô hÁØ~ó6¶¦ið÷” èŒm0¶í¾ï‹¢p¼?™ÙlÖ¶­rA¹Qô ú5¶ÁØö2¶m‡l'“‰rA¹±ô ú5¶ÁØ"¦éPî¿Å(ô騾¹¹™N§‡‡‡aéêêjøñää$Äæâââàà (Šù|¾úñèèèüü{Â^ðØÅc¿ùÍo@Þ+W®°5È_ò—Ì%È_Â÷øK±mÅ_|¡J;--b{ÜÑÒÒ"RVVæq\ Ø&úŸ÷ÿàN÷ÝŽæk.xÙœæó‰5‘'JƒænÞ•þõ¶ _Œ»íI_q8oËɲ¤š¨œæÜäÅkÕ¸áïÜ~Öÿ”=8ŽøôÓOAÞàà`6ùKþ’¹ùKø)¶­˜>}:n{Þ¼yZróæMè½®®.ŠmŠmŠm3Šƒq© 2ÀÿäÙãž{—]…é±±¡G ¶ïÍ\=¼£Ý‘úåÞ¬oæm*ÂkIövðàA¼^¶l™ñ„õõõ~ø!•ß}÷ݰ°°k×®½?–h\Ôš"õQŽæ’·áááx»dÉ’ÞÞ^‚N:Õ8þòÉ'Ÿè £Â )ôJKK?þøc¹D¼oݺµ±±ñ¥bÏŽK£ ¥W¯^-õoܸ¡²ÿÛo¿E)Çi·mÛfÒÒ}ô* éÐ)óçÏÇ¢&n2..ŸVTTh×Ožõîô¯ïÆÊ´Ê«ywÚ>Á·á~¹ä/ùK¿ä/áûb3ŸPM¯YµcÛ"­•SRRìäÓž9s&*[m)u~üñÇ9sæ ZgÍš5RG×]CÔ©rSàö KQgݺuZ8|‚´sçÎY/§Š±¯¯Oª‰BÞ´i“h,ß³g¼…0–ó«¬U±V´õ°°sÈzÂÄÄÄ¡ºcx±DëRgñâÅòBÅ6ŽÂmXOûÖ[o]¿~]Ï uäÎM€P·¢1q”ý¾Óþ²v½ŸŸß ÇBùSl» ›7oÆ¥ñ׫¨4÷Õ8N…ånÌÉ­8R°aiMçàûà}Þ®Õu81?€ »#ùÛÑÖ–9”·±|˜v@hßhõAæ’¿ä/Aþ’¿ä/Å6¤jÂŒŒŒööö³gÏŠ´³Šm•Xîéé9zô¨”@p>xð`ø ©¤Ç¬/æ3iŒ”Ô">qiýÎQi×ÙÙ‰ZC¸J!f>b[€ùϦ¦&ÜjWÔÁ¤7 E3£¯¡*­b…ú‡Æ7ò¨‰Ú‰Ø`’yÇŽçÏŸG9Σ3º¸¼1 ý/…ú5‹ùp5ˆ‰‰A6]ƒ$F‰}±-‡átÚóÏN9r—@kà†uŠÛ$¶åðÓ§Owtt`NoþþþË@ŽwŒÀl¶ý¾C0¡Å6që§¾ì‹ñ{3¿Q÷ãïX‚, Øð{{Œ…Û£¡aѼE»K´Ùƒ2W¡#nýtí…ïƒ&É_2— É_òwDBjn9êÎ;Z¨iìb[”³u\b€%«¹UlkLÛ¾tÝŠuÀ|¸œ X3®8B±­ŠËÔµ‚æ'·)¶ñPV±¸hcÌZ£px`}µ^É)MWÁmØÛC®à‡¿®Æi«ØÞ°aƒUlã1‡ÛöûÎ*¶1ÒñÒ;DÆÛDSo%v­TgƒMAâªbcL÷z>ƹe`ÓÑPÃ~-蔦kUÚM)Lþ’¿d.ùK#)¶­³ŽÖ˜g´ŸUlCpâµuï+|„]£DƒøsHÜ8æNåBÃìðŒ9^ëä¹ir¶L‚y$b‰¸ä´ñññ¦SACÚÛº?âðb‘Ò*kc†@Û¬qàðÿjb[#Ø‘õm¨K‹ V±­Ïh_lÛï;«ØÞ¿¿” û†ºC,^ ØžX¸óóÜ–Äà_‚©°ƒeLé>,m_ŸGÃb¼eûüFú%${MÞ¥d.*#…É_ò× 2—ü¥‘¿Û………C%|–­ž¬k¶ugfÝZuL«‘­@n-Þ4%N›;ä¸VUöðáCÓá’E À<í(ŠmÀšúK°}ûv«ØÖ]¬HmGlk|øgŸ}¦…ºèÝ5¤sGª0MNnÿ¯&¶ɇû‡ð6‚´ð¸4oPlÛï;«ØÖµ Õ¦cpÛC=¤M 4÷¹b+ÂtM“êNb-“ç8<Öæ¡SÐ5ÚMq•‡¸¢Œ&É_2—ü¥‘¿Û¦üd¦@bMÇ q5¨ØF¦.cM$µ²fº&–çÑB•¾¦ˆUta>ÜX" 7£é£+¶EˆBKlÕxº#´ŠmÙ$ ÔÍû™ÙÛªÕñ r!Epp°q5;æŸå ¼­ ã_Mlc-´5Ã9€½Ç4Š~„bÛ~ßYŶž iÏMO„DÚ˜Û¾Š+¹ûsÖ«ÿˆ.ݛךîÉ>–Ûšv¼d¯vY¨sciG]>@þ’¿ä/™KþÒÈ_ŠmÍà `#()Á+dÏ0ûl#o¢(FÌ‹¢‚l줳¦ƒŸŠî…ôª¨¨ÂÒÒRM&“ä"5Q§¼¼\7ÇÂl°Tƒ˜u±­Ù¹°ªü‡~Àå0 ehÝg[¦ú5¡:fø%C¸M±­û²¸ŠNêâa5½Ý«Ãš‚{÷îÝ(ye±­úÿ˜c×B‘Ö¸<ËŶý¾Cª3) 5-û°õºFLìÚµK ÷îÝK±íÌÀ¸\ºûn»îÒ’½.¡6ÆÕSéE>‡ž¯‰ÎZ#=U¼»óNÛ ÂG™Kþ’¿öA¿4ò—ªë–¡NUZCgŠütf[OeªVŸŸÿÒ a&SëC‹B›é©d¯fçÑ:ðáøÔ:÷>Šb£2}*ÐËYÅ6"íµP[̾؆òÄשŽ™j([½hOOÞžZËqˆ´3þ¾²ØÖ»’s¢‹‘[NÞê†[#ÛöûÐgAD‰Kú7­Œ{@ãh # ÓãÛ>;®ÿ´ÿIFSœ8‰ÀÌoÒ›â½×çѰm‰îY‚bžõƒº„2—ü%íƒ iä/ ‹fˆO£tüøã1}m®2Íøþû„¨.’ X·lóBØ„Y¦J)3›VAk·bçÎÆ™óU«VYŶޤUlc ô0Çb³¬ªñbñâÅ÷Žén­‰¼e(Qà>¡TEC‘êfC¥ Cr¸µkך ×Bû›ªé~`ª?¡ÆåµLX‘——'u0€bý»²iÇéi/\¸ 4ˆk›Ý-bÙÎtù€ý¾3eDÝ éÖ1ñnÐÁ†ÌºSlû¦Ë¯ï. ùe86¶òpC_½·{;Zãõ†ØÊ#Ò§û²×5öV¼ |޹ä/ùkùK#IX™wE¾k,¸ÅD¥u^T¡ê {ƒAøAG½‚¶‡BËÉÉÁ&äƒVÀL&öýŽEÆ,è7‘[nÖß¾}ÛÎm½7 àþ±þÙ´¬Ú&p <;’½c/ÌU ê ﵑG´$b¼Ð޶E0ÿO;’¾C4;ªuuué=¨†G$yDDZøîÝ»RH±íƒ.ÿæ½g~ÉÂr8߯°#Û—­°=ûPÞ6éßsÕáw™.ÕW˜Kþ’¿öA¿4ò—„%üüü }õêÕÖÍÃuãh¯A±íÑ—ÎoM7¶ôBýi_ux´¤ºïv¤~‰ŽÞ‘º¸´#ó…€¾Ÿü%mƒ iä/ K ê[áun¡òRˆ€çѼA±M±Þ+žÛEú|ZUWéñ’ éñ‚Ö”^ú~ò—üµ‚ü¥‘¿$,¸e¬ñÖ´m’9Ló“ë6]¾rb;wcz‰ÄšHùÞO¿x~b:¿º^WÙÕBl©’ÖY…ÄÚñ5Qg«aÉÜwå¡1eû¢J‚"Šv…ì@Xhî¦}9ë‘e40cÕ®´¯ýKüRÁü_á- ‘ B›åm=R°ãXÑΨâÀèÒ“åNWŠ«:zΉԲÉõße\LÈoˬè,®¿Vëþ§Nk:'ý^qÅÉo71—ü%sÉ_`.ùKÓÿrë/‹‡5!¹f>ÃF_TÚ£ ŠmÒøtE(¾î᨜—R}9CI_}eW)M!5hrÝwgªÂ£Kƒ±..8{m€c)Z`ÜmgÚ2ìïr$;n ·‡›Ä­´gUv–4ôÕQ³à‡\½¾§Œß>îùKæ’¿d.ý/YLþzÈ…d𮬬DBoÉ‘FŒ&(¶Iãœæóø¢Ç`paGŽÏøuŒR#µLJÙSaG ö;7ìN_>¼£Å* ‡ÌÛŠ!pÿŽwÉø÷©ÔÆ3Ø|%³9)çRj^[:~1”\ÎÃH<~= ä£òø%«ë­Á[–_-BÜC^[~Be5'cÊÂÑg³(Ú–»›»lOY<übÌ£õÚÇ/¾œÛ8JYj1Ì/—h½QÏo·ü%s}–¿d.ý/YLþRlÅ6iÜÐS.ßòÎV‡W{÷ŠÎ’ì–äxWTdñD— å/÷d¬<à܈ 2xYx\x_ç%Gé•üšžjOx üPÀOü8HmŒÃ³œ,=V´+Ô¹·í—òÇAŸ#ñøu‚gÉn¹€FxåKãÇ ÎæŸúU÷Ýv~û¿d®ç3×sùKæÒÿ’Åä/Å6APl“Æ?>¼àX‚¯x {Ùú®k5ÛNiˆ…ÏÆXø Ah„>^²7¡6:«%¹¨#§ª»ÜÛ§ ª»+0šŽAzŒ÷ã7 ¢ï¬O¦8˜·3ÂÇR´ÚÞjûç) Áöf®Æ?¿}È_2×ó™ë¡ü%séÉbú_Šm‚ Ø&-‰ør‡Ûð–*YÍIðïN_q¤`»!¾«‡ø¼5\«+êpb~ãâXi†Flè}-bù0íP­æ¥'Ä@>Á?¿}È_2×Ó™;rþ’¹ä/YLÿK±M$Åö¬Œî9Ÿõ?•eTXÔäÉþ #èèBR£CÞÑý9B“ÄÚàaÈY*Óй­,KÃ0ùç†í©¶íPþ6¼a%ÛP‡ãŸÕö¤¯èÞÿ‚ðHæZùKæ’¹ä/ùKÓÿR`PlŶ]º¬#_ëÈê N°h K¡’Ä諱†T"ÈjÿT4³­ŽËÝbÊõ‚æMm8c]f†½R<'ú~å/™Kæ’¿ä/YLÿKPlŶg]Z6öD¾PÏqK9—RŽ…µ^F·„ ¥ÈS‚4¤µ½®‘œœ†õcØÈËÉФ¦/§*"¿‹TÃÏ,&¸"^x*èû­ü%sÉ\ò—ü%‹é½ÛN§s÷îÝ111ÃÔq86l8zôè8Þgqq1î3**Êfý–––ØØØÃ‡ggg?zôÈþ…º»»w´RuuõÏ?ÿl½Ö õÃÂÂм}}}Ã_±¾¾^ê'$$¼ôöªªªöìÙ3oÞ·nÝŠ{˜2eÊKk>}útÑ¢E¨¬ÀQmmm6/”››ûÚ˰`Á£€‹‹¾þºuëpWC]ÊYª½þúë?ªZÿöíÛ‡ºÄûï¿ßÛÛK±M±ý_ Îu|W[e\L/ðWgƒMA⪺y  ?ø°éhhî&SVÕ ú~+É\2‚ØT¼À¿ÙGþ’Åô¿^ ŠmÌ—¢Ó§^*¶wîÜ)Ý1{öì9sæÈë·Þzë׊mLÏøs@ «¸Å”ò“'OLbuÞû¦úK–,ôrwîÜÑ:À… ­vÿþýwß}W«AŸ£ƒ"""q ý¼ùæ›>¤Ø¦ØþÏïtlqé~ïRÞY §Ž½+å°ƒeLé>LÈŒ¯Ï£a1Þ‰²}H~óKxÛš¼KÉ÷îßzAxsmð—Ì%seO`2—ü%‹éIX¯ÀÍ›7ÝÙÙé3b"Ù(ný.½ƒ'µ)¶‡Ñ½˜!Ç=H…²²2“Ønhh0Õw¹\ÒžÞƒNn9rŸ*>úè#Záï﯊Ú4KÿàÁLk˧«V­òJ.Plç`,œ}ÆÅóît'Ø;äháN¾EFÓ¤º“²%ÍC kóÐ)èí¦¸ÊC—®×Ñ»Ÿ¹vùKæÒÈ\€ü%‹Ébnýå°#¶¯_¿Ž¨æ_uZÔGœó½{÷^­ŽM±ýìÙ3é ]a^QQ!%—/_¹ØŠŠŠ¤BPPÐKÅ6*ŸZ?>}:>zûí·!³¥ÚÝ»wMunܸ!¡k0Åm= ÆJ^TÒSl“Æêì1Âí‚JA™ß¨ÿˆ.ݛךîÉ>–Ûšv¼d¯vY¨sciG]¾‡ó—Ì¥‘¹îý/,¦ØF4ò´;vL oݺ%…:ͫⅫW¯Æëƒ""‹œñ: å*ÛðZ§©ØÆø_|1iÒ$ÓFr¯—Þ[ccãܹsQ_ãçŸþÃ?Ø©ó 3ÛS§NEÍwÞyGÞ®\¹RÎ >*b[¿Ñ,vÄ6ò´É§H–fmùíŒìhòÁá¦j›7o6 X¾“:uu†2ŠmŠmäAqCpv³ÐÄ› µ1®žJºR/Ú8ô|MtpÖéÁ¨âÝwÚèò=–¿d.Ìu?èid1Ŷ†Oce¯–$%%©|Õ OhNYKbZ³ýå—_JeRdk@h ø0wÕÔÔ„jVànoß¾m¿Ž}±½cÇ9}ú´ëà<úª“­jÝ$ûóçÏ—$9׈wó0ŠôÑ+€b›b;ª$h,|CZÓ¹ÀŒUr‰ØÊà }õÞîíh×b+HŸîË^ר[ÁŸìÈ_2—Fæºô¿4²˜b™tµÆ„ë<6€•Æx‹Pð_›€À¶®7†²æ®Dºc ×XˆqY¨l¿Ž}±0oÕÃÀÂ… ­ÂvÄ62™/5çÑ«ßö·þúä“Oݽ\>Õ]²µéд6Óͽ´Ð.(¶)¶Å;/9FÑ%”^)8öK–Ãù~…Ù¾äðh…íÙ‡ò¶Iÿž«¿{ÿ]¾Gñ—Ì¥‘¹îý/,¦ØÆä­ÜÆþýûK‹e¾›QI5LóâíòåË_Al›²sÉvÖ¨?|º5©ƒËšS êÓ×8›ý:6Åvii©œMGûñÇñ¦‹Ož<‰¥Ñ#ßgm(áV±ýú/°îƒmZ¦.áå¸[=tµˆÇ´vëâÅ‹}ÖiRlÏÀX8{ä½Äߣ…} £â ι"åÌiK/ÔŸöU‡GKªûnGê—èè©‹K;2_¶™ë~þ’¹n02—ü¥ÿ¥‘Å•CŽ1MII‘iç´´4 /ô葼Fá¯Û(·f©ØFع1íæ‡kxuûuì‹íööv=Ñ·oß.¯Ñ,X©ŽiyIóff{‰¸+Ù:[?Eåá×l㊋‹1ÍnÝjkÑukîd4IÔµ2Ât¸ä×b›ûlã[;²x^„ú| SarZléóYXhU]¥ÇK‚¤Ç ZS^ö˜ë~þ’¹n02—ü¥ÿ¥‘ÅÛXá,“«˜^³f ^ã/æuåöªªª°(Ú4Gm_l¿õÖ[¯ ¶q'½Ö™Þ?üðÚµköëØÛ¨/VVVâíóçÏeöXÚ×xÌÞ#Y³Ý××§ûlc¿ëáŶ®ÍF¼½i9ý¡C‡^hsÓº÷់É%ÜsûÛŠmõ÷ÈYZÕU†·¯fºMEºì:1¬®×UvµÛ¨¤5Åc&!±öD|MÔÙêcX&÷]yhLÙ>,É‹(Ú^°¡_¡¹›öå¬GfQDîJûÚß±Ä/eÌßñÞ¢PP!Ô¹ }q¤`DZ¢QÅÑ¥!'Ë ÕM\ÕQL\ lrýwòÛ2+:‹‘g|[‹¥ß+®8_6˜ëþ’¹ä¯û™KþÒÿ’¿d1Å6"¥åN°#—Ì‘b0ʑ௃ƒƒ·mÛfš#µ/¶uNؾØV í–”¯[·NîJ€×ÐÃ6ëØÛë¦9gŒ)ÈÙ999#ÌF~àÀ=•± lܸєùLïjªŽ®KͱI›vtt uÛ:O±=(¶Õßpn„ëÒBû†@8§å¼”êkYIúê+»J±P é@“ë¾;S]ŒµpÁÙkKñÔãn;Ó–aO—#ùÛqc¸=Ü$nIn+;Kúêܲ‰ëwr'õ=e/ÌuÉ\ò×ýÌ%éÉ_ú_&wyW•^ßÿ= ýüüDcC0ãÅáÇÝ#¶1©Ž¼ÜµµµÆB$ñFÚ3UvêØÛ÷îÝC}:Egg§Î™ã$ýÅv^^žT@Ô·M±-Sîºû†Bä-6ǶVÞ¹s§|Š…R‚ z)‘íЭ@¼£Åº) ‡ÌÛŠ!pÿŽwÉø÷)´$6\ÉlNʹ”š×–Ž_ %—óðs ¿æ‡Qyü’€ÕõÖà- ˯¡î!¯-?›²š“1MáhŒ³ŽÙGíËÝŒ ]¶§,þ1fÑz íã@Œ‚_ÎmƒÌ´ºV°õFý Â>sÝÎ_`.ùKæ’¿Ëbò—þ—b[¢Çø]TT¤…2¿ê±­ºÔ´7V2ëÊd;uìˆmL€‹¨Æ<°é£-[¶è³c3³ŠmDãK…ØØX;bÏ%ŸBkY;BÕäÓ?þXµ´Œ’ñññÖG8€|ŠÍÞ¸fÛŠm‹Û†Áu•]-°ó-g&‡8[^çÝ+:K²[’ã]Qø¡ƒè²¡ü垌•˜s@P¼,<.¼/òÇ–^ɯé©ö„§ÀüDÀƒÔÆ8<ËÉòÐcE»BqÛ~)ô‰0.Ƴd·\@#ŒÊmÈž®þ©_ußmAX˜ëiüµ2—üõmþ’¹nà/ý/ùKÿK±­Z@ô²iû(«^µŠm™#ýàƒF.¶u¶ùÓO?Õ)eHGhB]:n§ŽÍ0rܳQ-yÈ$ê[teX8=±­âÛh›Äö±cÇò @¹QQQ’e]Ûo=¹)Ècº¨¬?G À£`u:ÚMʱ3ÙÏ?ÿL±í•4΀œ=,«9 nOFdž„’a¬º»\Rbb Ù Öw]«ÁØvJC,|6ÆÂ Bà 4¿%ÔFgµ$uäTu—{ùtú¨£é¤Çx?~Ó úÎúÔhŠƒy[03€!|,E{åT=1¥!8ÛÞÌÕ?>¼GOla®ñ×Ê\òׇùK溿ô¿ä/ý/·þh¾qK MI¶Dª /¶‘v[Ï€<^#\³Ý³u^éÊ\ƒº7mÚd³ŽM±­sÂ*>õ5N+[ Ë–-‰ØFÎ6©€°|›ûlË~l˜‚Ö,ñ¢Ì‡º‡ÀÀ@Õç¦ìwVèÚïÆÆFo%Ŷ;= iZ°úH* š î_Ê­W}uàB<9 îÞ}ÐóÝé+Žl×ø.ÙÅç­áZ]Q‡ó ÇJ34Â`Cïkˇi‡úk5¿êäÔÇáΖDþd÷XþZ™Kþ’¿d.ý/ùKÿK±=ZÐÂØ§Z CBB¤aÛÆÊ2Œ©T-)++S™º{÷n­cÛX þR±yi9\¡³î˜ãµ_GR»ARÿìˆñÖláºNÛßß Ïq*$$7E€[iÓ’ikvq© ÙÈΞ=«%¦KãŠÐö’]0þü—´c™ºnèm,¿xñ¢l$¦Ð”—¬E§Ø¦Ø¶–<íÉX!ÕÄšãÉ?v¦-ŧXàäiþ #èèBR£CÞÑý9Âï˜ÄÚÝaÈY*Óй­,KÃÐøç†í©¶íPþ6¼a%›SះìI_Ñÿ¼Ÿ?Ù=“¿Væ’¿ä/™KÿKþÒÿRl{ '1MŠ­­F+ÛVWWWFFæf=Šùvl õjulÞ<îiØ1ጅß…îKÀöÝX„IïÄÄDLækT¼]PlSl«¹º+ð-”¹Z*‡ånÁp¬~šXwR~xˆÇB‚,šÂR(à}"Ö>ÙA퟊†`¶³ÕèqS®4ojÙᗙaßÏ܉D(LþZ˜Kþ’¿d.ý/ùKÿK±í^Å6ŶVaÌqMrF^Ï×GJÏè=‘;t|ÝRÎ¥„ca­—Ñ-!C)ò” im¯k$'§¡÷±‘ –“¡IM)^NUD~ë!øÉ… ®Ïüö!1¿da.ùKþ’¹ô¿ä/ý/ŶÛAÛÛºÐmò3]·—ÄßüqŠaC²Ö3UGŒ[ƒø;–`ÁnR¶*u£¡aѼE»K´Ùw¥[uÝa•GyDa€Ç~û¿æ’¿äï„d.ý/ùKÿK±MÛÛ³0¾Î^ 㬑ź§…ûW^e\L/ðWgƒMA'ÆÍëÖhø‘‡MGCs7iG SÐ5ýˆ·øÆï; s=‚¿ØÖÊ\ò—üE„êX1—ü¥ÿ¥ÑÿRlÅ6÷ÙþUƒ¬rlwéïRÞY §Ž½+åºøµSºƒ¸ô»ãkXŒw¢l’ßH¿f¬BîYyíNŽpŸ^û6sÉ_òWTܽû·Æ3ä/ý/þ—b› (¶)¶õ'{†dIKÃÞ!G wê.Bé’êNÊ^”b4¬ÍC§h”£Ø¥ëu/<ÛÃ3—ü%ã*3É_ú_ý/Å6APlSlc´{ì\V(e~£Î#ºto^k:=«'[nkÚñÌ=b¡Î¥Y/<ÛÊ\Oä/ü%éiä/Å6APlSl#'ÊGa M¼™Pãê©ô"ŸÇCÏ×Dg­‘Œ*ÞÝy§í…'b[™ë‰ü¥‘¿ä/ý/ü¥Ø&ŠmŠmØèn¡Y­[‰È™3¿IoЧïô^C:ݳ$³)îY¿§ìûO±mŸ¹ä/ùKþÒÿú¬‘¿$,A Û¹ðXgU4Z¾!­é2|Èic+7ôÕÓ_z»5^oˆ­<"}º/{]co…Ozb70×Ê_Ïa.ùKþº‡¹ä/ý/ü¥Ø&Šm7ÀSœ½øfç%Ç]Bé•‚c¿da9œïWØ‘M7éKVØž}(o›ôï¹êð»nHwÌ}¶ÝÀ\ò—ü%séiä/Åö (¶éì‘4ö5¼ò©Î¹"åliK/ÔŸ¦kôUKªûnGê—èè©‹K;2)¶ÝÀ_ûÌõ þÒÈ_Šmú_ùK±MÛtöxY¼/ ý_m;Sar*lÉ,,>oU]¥ÇK‚¤Ç ZS(¶ÝÀ_ûÌõ þÒÈ_Šmú_ùK±MÛtöêï‘¿´ª«ìWD·©H—ýB'†Ñ°8Pú½âŠ“b{äüu?sÅÈ_òwÂ2—þ—FþRlÏŸ?ïéé¹~ýºÊ÷îÝ»ÿþ«\† Ø¦³WÀ¹±ìj¡Í3 ø ‡ø;¾r^J¥ÿ›h–\ÿü Õ÷”Qlœ¿îa.ùk5òw¢1—þ—FþRl---ï¼óÎ믿.-ÿÆo,[¶ì‡~0ÖùüóϧM›]VV6uêTT[¾|9›Î¹@±=kîìÕß#eKjã™—~¦*\*väÐóMLÓµ‚­7êÝC%`®•¿nc.ùK#éiä/·þ"^³@$wkk«V›9s& çÏŸ/Ÿ¾ŠØ&(¶¹Ïö .UXvµ`¨c±{§Ts¶:èó&²Éž®þ©_ußmç÷ûŶ}æ’¿4ò—þ—FþRl·nÝ’ mHëüüü ’<,,Lºc”ˆ-7ŠmÁܹsCBBJKKGtm‚b›b–ÕœœµíJû¡JÖ ÕÝå’3¡6†ÞŽS‚†½™«|xÏÍ̢ضÏ\ò—FþÒÿÒÈ_ŠmbÕªUÒÚíííÆòÐÐP)OII1‰í   Q»sÉ_ùKÿK#)¶‰I“&¡©çÍ›g*Gš4é???£Øž2eʳgÏFñŠmŠmÍÀqjOÆ ©v8ßOò6ôÕíL[Š’¼¶ ©F£áŸÿ{ÒWô?ïw'³(¶í36‘ùK#éiä/Å6ñèÑ#iêÈÈHë§,ÇGŸ|ò‰Ql/X°`Ln… Ø¦Ø†¹º+âk¢‚2WKå°Ü-XK&¾ßXFþ5nÚ‰„bû•˜ëhŒCybÝɉÉ_ùKÿK#)¶‰¶¶6iꌌ ë§3fÌÀG³gÏ6Šmd)g»y:(¶sàÎ^¬¶·:±öDHöZÔKi8c¬@£¥6Æá#ÁáKžX˜ëábÛ>s87ìÏùùë6#­Ì%éiäï8^ˆèîî–¦FBrÓGOŸ>•°ãÅ6Å6iìVg/Öp­m;R¿ÂQùŒaûs£å·eâ#¢0€žØ>ÝÉ\‘Ù0ü¥‘¿d.ý¯ùK±Mô÷÷KSïܹÓôQ]]|àn±MPlÓÙ«É‚±êî º7š)âÿ»Ó—Ó{šØVËlNÜž²Øiä/™Kÿë›FþRlÓ§OGSOž<Ù”öìСCÒ ………ã&¶ Šm:{9ªôJ¾±F+»Z(ÿôÄž&¶íó—Fþ’¹ô¿¾mä/Å6rií… >yòD ].—l¾ ·ã&¶ Šm}†ä7¦Ñ ÛÃz¦Ø¦Ø¶Ï_ùKæÒÿú¶‘¿ÛÄóçÏçÌ™# thÓ¦MÓ·ã)¶ Šm=¶ú4Òhñ®(ÏÛÛöùK#É\ú_Ÿ7ò—b›xüøñš5k¤ÍÜÈUn¬6kÖ,”¯X±‚-F±íé4ž5_röÇŠv i´ˆ¢]êì}Â\Ûä/ü¥ÿ¥‘¿Üú‹¸uë¶lw8]]]˜ñf›PlsŸmOqö°‚ö,)¡ÑðÏ ÿü¾ó\±MþÒÈ_ú_ùëù„%ŠmŠmŠí¨’ )¡ÑðÏàùΞb›ü¥‘¿ô¿4ò—b› <ÛŠíÀŒUøë¼ä Ÿ£áß@þ%<ßÙSl“¿4ò—þ—FþRl„‡‚b[@±Tw4ö5ÐÛMdÃ?þ ä_Âó=Å6ùK#éiä/Å6Ax((¶)¶õ¨Èâ=x^è_Û[MŸ71 ]^àü3à­ç;{Šmò—FþÒÿÒÈ_Šm‚ð).PlçÀÇœ½úûCy[«ºÊèù&š¡ÓæmUOó½­¿„¹¾!¶É_÷ùke.ùKÿK#)¶ ‚bÛ ðg¯þþ€scÙÕBú¿‰ceW 87¨§÷x±Í}¶É_÷ùË}¶éiä/Å6APltöê#µñ ½àD0t4º[==Ŷ÷Šmò—ü¥Ø¦ÿ¥‘¿ž+¶ ‚b›b›Îv¦*\Ê£Š1æJwèÃêèbékt:J(¶½Wl“¿ä/Å6ý/üõt±MÛÛtö°¬æ¤à¬5øhWÚ×ÉõßÑ/úž¡[ѹèbt4º%Û> ¶É_ò—b›þ—Fþz´Ø&ŠmŠm:{ÉØ],°…ø0ºRö¡‹%Ŷ/‰mò—ü¥Ø¦ÿ¥‘¿ÛA±í•4ž5_wö:þzjOÆ ©v8ß/ýây:Kï5t:Qz݊Εr÷‹md®ˆmò—ü%é}ßÈ_nýEïÞ½;**Êþ!ßÿý?üðÒj<¸~ý:þÚ9ç³gÏúúúnÞ¼É¡Øæ>Û¯~”«»"¾&*(sµTËÝâhŒ£ãô.C—¡ã¤Ñ•èPt+Ê}ÀÙsŸmò—ü%é'”‘¿ÛÄÖ­[ÑÂS¦LyiÍ»wï®[·îõ×_—NÁ‹÷ß¿³³ÓTíéÓ§ááá“'OFÁŒ3‡Û¾¯ƒƒƒQáË/¿¤Ø¦Ø¦ØÎj{«kO„d¯•C°SÅùšãÜ¡Äà „n’mE`è>t"ºR+ø¤³§Ø&É_ò—þ—FþRlSlß¹su^³’ûâÅ‹Z­¿¿Þ¼y(·âäÉ“C¼¨¨H« UçñãÇS§NE…/¾ø‚b›b›bûåÖp­±Oûsþ„£ÄŽír4ž­ëuѳzŽ¡;Ð)èí&t:Ý'|ÛÙSl“¿ä/ùKÿK#)¶)¶çÎ+}±fÍšæææÞÞÞ½{÷JÉ{ï½§ÕBBB¤ðÝwß---½uëVrr2¹ÈòŸ~úiÐ óI“& #¶a^]]Yt©@±M±M±ýë,³91²8Ð/å¿,@Zù]yhnkíøºî~A¡›ÐYZÁ—=Å6ùKþ’¿ô¿4ò—bÛ€5Ï÷îݦ&“!}mÖy5±ír¹¤#Ö¯_o,_ºt©”ß¿oñ÷7ÞÀ[äÅxøð¡V;wîœTs:Ö“ôÑGøh(±­ Ø¦ØöˆKïN_Ž/Öêî oqö%…ÕGÆöᕇ³[’k9Öî¾qôšœ–”Øª#h|ãP:ºÆ~œ!¬»¿nÛä/ùKþÒÿÒÈ_·bûùóç³gφX-++CÜ5懥°:((šÙX¹±±Q'œÝÏ?ÿ\R—Ù¯cÛW®\™?€””)Yµj•n:9È— Aæx‹Il©–››k¬öèÑ#ÈrT+//7=/³É¤÷Ê•+ík„ŽSlSl¿:r0ºçŒ( Àk~[†w9{µì– ÇKöîHýR¿ã«ð‚ð7…íÙôÇcaÅ—s“êN"VÍß±D›]€Ž@wŒàÌ>¸õ—•¹nே‹mò—ü9sÉ_ú_ò—üPlË#[E¦l#¦Zj655Y+ˆ,¿}û¶ý:V±]YY)ÕvíÚ%%o¾ù&ÞB¥k“ì ÂÕާ°V³¢¥¥E.:h_ã>{F (¶)¶Ç‰5‘øbMi8ã¥Î^¬²³$¥!Î&0c•œYƒÜ¢ŠSÎÈ–’¯l´êîòŒ‹çO”í ÌüFÚVœbÇNüÿ  ´2Ŷçó×Ýb›ü%É\ú_ù;f ØI|öìYˆÌììlLwKá‰'¤¦LzC"fË¡ñ‘ÔA2p;ulŠmıË[èá´´4Äu‹è…ß²e‹qöÌ™3QþÁ´¶¶.X°ç”3/\¸ðêÕ«ZM§»EÃc o­bÛ ÈxŠmŠíñGYG¶l¤é¥ÎÞjùm™V?R°Ã0Ü. 9×®<ä¼”ú«ÎÆ•`gªŽìÏÙ`lIÿÔ¯0¬žXw¢¨#ÇTŸbÛ‹øë~±Mþ’¿d.ý/ü#PlCôZ³ˆAèJ‰d[»v­ñpL>£ðí·ß¶_Ç*¶‘÷»u¸(ÞBí£‚¬Ä~ÍÜÏåË—å@Q×Ó¦M“ëšpáÂãm|ûí·2 Ž]»)¶)¶½ ÏúŸÊ²±¼¶ ßpöj }u9—Rààu µ}9ë1 Í0àÌ\=•RŸ†¦@ƒ YÐ8h"S£…ån>ëŠÈkMGÃê!ÛÞË_·Šmò—ü%séÉ_òwÌ@±ýᇺË4€ßx •+ZYÇ4ZûÉ“'˜j–te6êØJ†…Ù¨ ð÷÷ÇN]PÎØâK·ÑÆÞÚªíueuö6oÞ¬›„A·Ë9³²²¤§Â[ŠmŠm/ƒ³%ß­‘Å{|ÊÙ[ܘDa¢°Ôv§¯À23 !§7/½R0q¼;ŒÇ㣬-ƒ(µ“岚“jzªŒRlûÝ*¶É_ò—Ì¥ÿ%Éß1Å64ªé£ŒŒ ãŒ÷† ŒÓËÕ>}úôÍ›7µ¾:¶ÄvUU•žiÛŒ·*‰Äµ\«!—›ñ ”ò={öàí7d`Ó¦MxK±M±í}øñá½€L µ1¾çì­æê®Èmu$ÖÆ`±Rwú]ø£ÉÃù¥,Â`|LiÒ`¡üjQýµo÷ëx<…GÃâ1Mަ@ƒ YÐ8h"—5G.Ŷñ×­b›ü%É\ú_ò—ü3PlëÚlk:1L Kî±íÛ·[¶1%~íÚ5T°QÇ–Øîì씣°ZÛôQBB‚|„¤â*†q9É⦀º–jXÈ·X¤-o±wõ/ЄçòVò·QlSl³0gnè)—oXç%‡ï9{ÌùéMñÌþ²S¥ÕKC²×Éß_W}ôBý©¬–d,šBæJ£‚[Âáöp“¸UÜ0n7?èCáañÈxp<>ÁzBŸÛ¾Ä\+}\l“¿ä/ùKÿKþ’¿Pl‹|5³ÇòQ[[›"í´÷ºuë$Ù˜¯q;uìˆm„Ë!8ƒé#ì&á$x‹uàx=}útëIäÒÈ ¦yÔ†ÇáÇ)¶)¶=ý$§ù<¾a‘M´°#gB9{«!d+¯-]F ±P mb„¶zÍPçF¤-ù®<ôœ+ò|M4¿P:µ1~4³9{r`9’Ç yK.çaÌŠÎøf\«îZMc_= /ð…øP •qÄá8 N…â´89. ár¸(.mýb.Àƒàq~™1H—È4÷÷éu?}Gl“¿ä/ùKÿKþ’¿Plc¦×ô‘&‡úýñÇ].Wmm­~*™ÌDîvêØÛªr…Ž×Ö)k‡GÉy†×Öí²õ >ŸdN¿ËÛS§NQlSl{Á7ÈéŠPÙ')C'œ³·ü†ý-át±ÇÉÙêc1eû°Îj_öúiËð b¸Ün ·‡›Ä­â†qÛæéÆënைmò—ü%éÉ_ò×î³ië䰨⼼<©†Ørcââb)¯¨¨°SǦØþôÓO%>üÎ;ƒ.ƆªÇ[ÌÆËÛüü|cµºº:)?pàÀP—ˆˆˆàšmïÛÛºí',ýây:{›Öp­®¢³CàȃT¢ˆ‹­<|ª"ìDÙ~’a£Ñˆ¢]ˆÃþ.ó¶pnD¢Ñà¬5Ø09Qàžw¤~…ao^à- ñ* *ãˆÃqœ 'Äiqr\ÂåpQ\7€Ûðü¶âuwò—b›üu¿‘¿ô¿ä/ùë~PlË<°ä G®ï•+WJ!D)JîÝ»'o!ƒU“c¥´®|ÆvêXŶ¤Ÿ6€èèh)ioo—CæÌ™ƒÙl)„¢†ü–B)Á}â<2;-òèêê©D«ã–(¶)¶}ð$½1V¾m‘;IDéìÝl4þXw)¶Gn4ò—þ—Fþz(¶uqµ†X¿÷Þ{º»gkÜ5³çΫÕåÛ~«ØF¶s©³k×.kbs™uŸê»ËB²ÖÈ—/)5ôÕÑÙû†Ql“¿Û4þX§ÿõ£‘¿ÛA±íxÚÿ$£)N¾‘8»_ÐÙû€Ql“¿Û4þX§ÿõ£‘¿ÛA±í½è¾Û](ßÂ!Ùëjc»…ΞF±í½ü¥Ø¦ñÇ:ý¯ïü¥Ø&ŠmoGÅ•Üý9ëuWIlƒ‘ךNgO£ØöFþRlÓøcþ×7ŒFþRlÇÆÆ¾ Šmß@sŸ+Vr·ˆÑÙÓ(¶½”¿Û4þXèi4Šm‚ Ø¦Øž5é»?ßÌmIDú:{š‰m2WùëÑb›Fþ’¿ô¿4ò—b› (¶ù ²Ó±_ÍÕÝtö4:{/bîîôå¯À\ò—FþÒÿÒÈ_– (¶)¶Ý„ˆ¢|5ç·eÐÙû°ÑÙ“¹ä/ü¥ÿ¥‘¿$,APlSl»‰5‘øjNi8CgïÃFgOæ’¿4ò—þ—Fþ’°A±M±íV”udã«ùp¾½=™KþÒÈ_ú_ùKÂÅ6Ŷ[ñ¬ÿ©,þÌkË ³÷U£³'sÉ_ùKÿë³F£Ø&ŠmŠíÜx`w:[ñíY¼gb:ûçùE+þ¸rãJyxo7íÚäÕÅ­¿È\ò—Æ­¿Æ™¿ô¿ä/ùK±MÛÄï8–à :¡6f:û]a;ñ/ñßüwÿ¼]ñ§åx;õ™êÕE±Mæ’¿4Šmú_ò—ü¥ØÅ6ÑÐS.ßÑÎK:{:{Šmd.ùK£Ø¦ÿ%É_Šm‚çÏŸ÷ôô\¿~ÝNå{÷îÝ¿ÿW_ƒ Ø&ršÏã;:0cUaG==ŶO2—ü¥Ql èÉ_ò—b›hiiyçw^ýuiù7ÞxcÙ²e?üðƒ±ÎçŸ>mÚ´èèè²²²©S§¢ÚòåË_åbÅ6qº"_Óþޝœ—RÝìì+;*2*2j»kFxž†kõ¹µÎ²K¥/­ÖØ×`ÇÙ×÷Ô帲zë_áfð8ÙÕY®Îê—Ö,o+³sÂê+U¥—J^­eª.WâY^Z u › Ñ8Û>É\ò—ü¥ØèÉ_ò—b›HHHx͑ܭ­­ZmæÌ™(œ?¾V Ø¦Ø&Gºí',ýây78{8ÑU›Výë¿ø×Jàû¿þÛˆ³Ç´Âøýÿ>eꔿú›ÿh=vößÎÆGø‡?ÈÛ¤üÄ·ÿúm=œ÷ßò÷V'º3tçÌ·gþ³ÿêŸÁfýß³¶‡ø¡dPgŸVê@M=á¿ÿ?þ}b^‚Íç:|êΠÇâñ˜ø…aªvü|”ÜŒÜÀú𽘤hc…­[ðŒó>›‡_0¸[Tû‹)a¿M`™•ïýýßþóÿñŸãXyäû¶‰ËŒÃ!¸Ûš.×g_þrÃ…Û>É\ò—ü¥Ø¦ÿ%É_ŠmâÖ­[2¡ iŸŸÿàÁD’‡……IÌš5 ±åF±-˜;wnHHHii)й@±=kžß»é±ò}}¢lŸ«§rìœ}E{ùŒÿkÆkƒaá’…Rçãÿ %éeiÆcብ|õæoð6¹ iÐóLúW“Š›‹äŒñõçÖ:ð²Vg/®ÑZùàɃ/}®€ƒÞŒÉ=/]³tÐjÛönÓ:KV…’÷¿ý;øc¼go³M`¸ÛAŸâÃùÖu×J¨øH)”ÓºÓÙ»d.ùKþ’¿ô¿ä/ùË­¿ˆU«VIk···ËCCC¥<%%Å$¶ƒ‚‚FçÚÅ6¿Aò[Sä+; mé…úÓcäì¿üæËÿìÚ¿ú á^Ù=í8Ç&…uFï.œ”·ßnY-G™\2†œñö÷õŠÃ>‘ƒ°1ÅÉx9€Ái9äÀñýê/ƆÃSÛ+žÞêìÿøÇL)NqÖ8·m• QW_., NTjbü›š`êQax@)¼P˜¬CïZílVêày1« …2· ÎÁþ¯×}½/rŸÍ6ɯÏÓ_Çâ/|ÒÙ“¹ä/ùKþÒÿ’¿ä/ KLš4 M=oÞýHæÄ÷ë ÔMžW–©³Ç9 òµ¦ï9{2—ü%É_ú_ò—ü%a‰GISGFFZ?E`9>úä“OŒb{Á‚l7ŠmŠíÑG}wYHÖùúŽ­<ÜÐW7ZÎ~ϡݦÁfµOþéÿ•Ľ-[»LÞfUeêò0)Ù"%Š×¦ƒÜbGR¼N)º ‡øû™.'ƒÍVgcMÙVà8e¸]V»áÌF“Ñh%›þ¦ã¢z8ÆãqBIÖr.ë¬ÔÁ¿éf>]ô©ñÙÕÙ;kr´Ž6Áy‹È=Ó%B£ÈG'“OýžÃ{ð–ÎÞ·™Kþ’¿ä/ý/ùKþNpÂmmmÒÔÖOg̘fÏžmÛÈRÎv£Ø¦Ø<í’Ñ'ßà™ß¤7ÅŠ³_úí£‹t !dx›Qž.o×ïXgo†ëÕD£‹VüÑ‹õÁ¼¿ƒëBà>2…au™érvn°:{ŒR[oLòµ ljæPUè> ãåZˆµ^Èz§.¿9Äö ’OqŸpÆFCT›|„¸>yRk+Ùi¸À M—w¿·ÔÙË 4:{Ÿg.Œü%É_ú_ò—üÈ„%º»»¥©‘Üüµóô©|„¿(¶)¶)¶ÝHË»íÑ%ò=’½näÎ~îGs­XbÇâŽJ[aq””üå[)yJä­qýãóÑYl¶&#AôW^].*lܹQJJZŠM— 9luöê¹­cððå’Uu(gO×tЬ39¶|ý×x;<0*¯.1oÆÛ°Ó&5é%°6ÌèìÃFgïóÌM¨AÖ%ò—ü%éÉ_òw–èïï—¦Þ¹s§é£ºº:ù( €bÛ˸@±;¯îøŠ+¹ûsÖã«|äÎã»C `#ïˆÆh™ÆÚ‘+EcÀ×Ät •ñC)FŒÛ~à5bº gÈ1ŸguöX»eª¦i`þú?ý5^cWRø{£áÒÆÊøUt¤•e`Œ²ã# ‡Ë[\ ©S5ļ ïì‡o-Áò³¡.ˆ;Osön 0™Kþ’¿µuùKÿKþ’¿î¿1}út4õäÉ“MiÏ:$½PXX8>b› Ø&šû\#wöêÑá¡­›UÊG2 +k-“ ×ë¯Ý¾í|N¼) †ºå(}!Kª)Ѩš¤*µ®ÓÀ3Ý’u]…eº.nFü¨îMWµcêàqµŽþDÀáH£Š×Ã;ûáÛD?ý»ÿç}-ÔÅo¸ ËØ(¶'sc%ëùKþrŸmú_òwó—b›@¹´öÂ… ŸQ.k½°¦ëí¿~§RW'uUÏ€¹—:ƒŽ¬+ð©qÑîù¥?b4*~Íà÷ö ÑÃu]Y~}žÞ!ÂÏgUï ™Wð°Ã8{›m¯—F5\Ò‡ÂJ³±pöø—À?þ=è‰É_ò—ü%sÉ_ò×ÃùK±Mܺu ‰-ÂÃÃGWWf¼ÇÿžŠm"±&ßé) gFèPDÒx±rÊAG¯‘MÔ4­†±sG7aÑÊEØíÓ¸ KF¸ó‡w0|ntö2¼ ß¹Öo­úc©€»µóP9®lIå"ÐÃu#Mõ÷¦j¸Ü7›¾Á³˜‚ât1˜ý6ÃÖ£ú3Hœ1hk ìÔ2Bÿþ1ðïAOLþ’¿ä/™Kþ’¿ä/¿(‚bÛM˜5€>²Žl|§Î÷¹{Àð0öÞ <ˆl%ð¦âê^ÍàeÙµ5p œb Þ…Öñfìê…jOÄXòK‡Éã2ã°7 ®Èïû–”Ÿ¼!àO¸ÒÃ`qÚ ÕñÕü‚ý`Vz©%£nÅÍE‘ç"Ð&û£öa¹JÆÎð/ ü{¼p?È\ò—ü%É_ò—üåÖ_áí Øæ7ȳþ§²l,ï—H6 ÿ ²` ÿü¾s?È_ùKþÒÈ_– (¶)¶}ΖD|³Gï¡“£‰áŸÿøÇà÷ûAþÒÈ_ò—Fþ’°AçE±í#øñá½Ç|¹'ÔÆÐÏÑðo€üKàƒßwîùK#É_ùKÂŶ§\6ut^rLd?Gs¶:ä?ÿü¾#iä/ùKþÒÈ_– (¶ù 2Rä4ŸÇW|`ƪŽœ‰éçhèzüàßÿ ü¾#iä/ùKþÒÈ_– (¶Ýܼð9œ®Å½¿ã+ç¥Ô‰æçhètt=þðo૞ØÊ\ò—FþŽ”¹ä/ùK#)¶ ‚bÛ>¸í',ýâù‰ãçhènéwÝØ“ž˜ü¥‘¿d.ùK#ùEAÛ£ "½1V¾÷O”ísõTú¶“£¡‹ÑÑÒãèzƘ‘¿4ò—Ì%i>É_ŠmâÁƒׯ_Çßá«=þüîÝ»÷ïß·yÚ›7oöõõ={öŒ-L±m D~kŠ|û¤-½PÚWý ‹.–¾F§sAùK#É\ò—FþŽÑ…ˆ®®®äää”wÿâzúôixxøäÉ“¥_€3f8kÍ–––>úH«Mš4iÅŠë©ìr¹†ªóèÑ£×_uzzz^ÛÛÄÍ{ÏT„‰8œïWØží[~޹X²Ñ­Ò¿èht7³§¿4ò—Ì%iäïØ]ˆˆˆˆpËô÷÷Ï›7ïµÁpòäIcÍÊÊÊA«M:õáǃžüÖ­[o¼ñÆKÅöéÓ§¥Ngg'Å6Å6ñ_Pß]’µF\Blåᆾ:owr´†¾zt¥ô):]ì“©J ò—ü%sÉ_ùK±M±"}÷ÝwKKK!1».óÌøûÓO?I5L_«lÆ}vww·µµ-X°@JöîÝ;h´ùܹsñé0báèQQQRbÛ.(¶g àÅÄÀÓþ'Mqâ3¿IoŠ÷^?GC÷¡¥7Ñ­èܾ÷1—ü¥‘¿ä/ùK#)¶oܸÌöŶ{_¾|ëŸížßTBãûÓ8;}îÜ9¹§Ó)%’ŒŒ £œž2e gΜi=ù¡C‡ðÑPb;//OÕ;Å6Å6¿A^‚î»íÑ%â$B²×%ÔÆ0w‹weaA—¡ã¤Ñ•èPæ¨ iä/ùKþÒÈ_v„@Œ4¤ìâÅ‹±$+œ±4Zg’19¬áÖÓ¦MSñ‰×Ó§O×3ÔÕÕá ò‘L8oݺõÇ´~Eppðüùó1#-o1‰-•uëD]D½téÒ%K–”——K nÉ*ªå ¨¶iÓ&Sycc£œyË–-ƒŠíÄÄD)§Ø¦Ø¶ ºüŠ+¹ûs֋ÀE—給{²“£¡ƒ¢K÷j—¡ûЉL9* iä/ùKþÒÈ_6 @Ó‰Y奨ÜÞÞ^ëGÆõÌV BË6ϯxï½÷Œ'_³fˆSéîAƒ½M«¸Qø¬æXÈúÀHÁ bûñãǽ¿CÛvA±M—ßÜ犭3ø?%Õ¬í­öGCw SÐ5ÚMè2tÜ‹1}?ùK#É_ò—FþRl˜y†æÄ„shh¨”`"²‰¾1_-…x:.%˜ôNJJºwïÞÕ«W5Ÿ&‡mž(±™j¼þàƒZ[[1Ý-1áø»páB\HB0¹ fēϞ=[&Øqxtt´UŸ/[¶LÎóóÏ?[Ŷ'Nœ Ø~PlOhÜýùfnK¢¦oñKùcLÙ¾ü¶Ìñur4tALé>t‡ôKpÖ·è¦;?ßxA¹ä/ù;f É_ùK±ýþûïš™ zu¨5ÛË—/—’ââb-üþû讀Öþù×®]ƒ®Öðrèa‰Z—Œh&\¸pAªÅÅÅihºµ‚Øz[—IyUUÞRlSlm«MתN•ÐÜÎqÕGóÚ2Üéáhhp4;_;âTùþ¦ÞÊ™Kþ’¿ä/ùK#ÇÛõõõ¦=·t:z(±-‘áØõÚtÎ#GŽ`éõŽ;ìŸP5ö_|‘=€Í›7ëâpÄx£vá6î­üáÈ[Žøö7ß|S 7lØ 'D}9çÎ;ñ–b›b{LPSSc*!nýÔ—Ó|~oæju6þŽ%ÇŠv%ן*»Z8Eó¢‘ÑÔÚì{3¿É¾î '&sÉ_ò×mÌ%É_ò—ü¥ØFêoÓGÈ‚†r„v[Ŷ¬j–·È@6òóÓ@PP±üàÁƒR¾gÏI«¦ÑìX¿­Õ%® Å‘,ò^"Ì^Ž·ÛÛã¢õF=ö´8œ·UÝloÖ·'ËC3›“j{]#qo44 š‰&5¶ð‘üm™Mqm7^x ð»üýÝï~§%ùKþz)s ò—ü%)¶!J­avA*¶ÛÛÛå-öЕó[£dÛ´U˜®—¼å§N’·X°m:¦Íå#„¦GFFÊkìVý SM cbbðöÊ•+ÛÛîñýƒÛ®ÎÂøê£+né`ÞÖs®È‚ö,ûކæB£¡éŒ-˜±ê|õÑš®¢ïÜyám@òLð÷÷¿ÿ=™Bþ’¿ÞÎ\‚ü%É_ŠmÌ [?zçwðÑÛo¿=¨Ø†òÄk Éùù­ÀGC©q„ˆë^_r'iii¦j‡CÓžK‚·áñÑGQlSlîß&´£ 5Uw óKY„tØ¿[P:/9ª»+ıÑÐÎVGbm M„†2¶šÙs÷ò o–¿Ÿ~ú)ÙAþ’¿d.Aþ’¿>À_†‘ß¹sG e÷,™X^µjÕ b³ÍòvΜ9¦sbë¯7Ú?ÿ @Öñ¡fÅeï.TÀëË—/Ë% ŠMÕΟ?/¡Îþýû'Y ËÂñoO±M±=n =}ˆ 0 §Âr7ª÷RÛ¾âHÁöØÊÃiMçŠ/ç6ö5L׎ÇÄÃâ‘ñàx|4‚µeÐ\h´æ¾šÇO¾ð |ýõ×à/Rtä/ùKæä/ùëü¥ØF06ÞZ³vã…Ul MJ=z¤…º)÷ºuëlžø ??_ u¡µÆc¶èvë$ù‡~(5­€ °×lSl °ÞH'?}„÷ê«ùpcÇ‹÷ìN_nurûrÖ/Ù›PÕ’\Ô‘SÕ]îí®€Áãà¡ðhx@ëS£)Ž—ìIk8]ÝY€&zòì‘ïõ>\þo~ó„$‘¹ä/ùKæ’¿ä/ùëüå>Ûªfø-ó½ØÊK uitmm­” l[J>ûì3I9öàÁƒO>ùD÷³~ÝK }!D\Þ✲û´´Šá®®.Ô‘cõKU—^ûí·Ož<‘BÙÍ[Ý)¶)¶Ý‡ý¯ÿõ¨_¸wÿ֥뵈Ñ:W~0w“Õ ŠíÉX‰=6Žíü®<4¾&Êч(¸Ò+ù5=ÕžàÎq¸Ün ·‡›Ä­â†qÛC=ö\õ<8ð‚ð6æä/ùKþ’¿ä/A±-²V"´YYYZS£µu ¶N Þzë-`MQnÿü d&—rë¢kÂÛx,6÷Bi×ivÜ予yÊüáÇÛÛnr9âê cw âé³'=÷.#ËKzcllEèÑ‚í²µÉ0¶#õK¤ E"“¨âÀ“åNWŠ«:ïŠÄ²4ìÒ‘Ú—ÞŸÕœ”s)5¯-½°=»är6ð¨ì*uõTÖõºûêax·(ÄG¨€j¨ŒC†‡§6žÁ©pBœ'Ç%p!\Å¥qÃß!‚ÇÁCáÑð€Ož=f_“¹ä/ùKx/É_ò— Øž’„Ëü¶ñXS`¹lE†ÀuÓ,Z´H·ÈRnš®·B§ô»»»É[ Ø–ýèÜŸ$†èÞäŸ=w;š¯¹*®8±¹hbMä‰Òàƒ¹›w¥ o:î†ÛÀÍà–pc¸=Ü$nÑh¸mܼ<áKÌ%È_‚ü%É_‚b[¶+++1‘[TT„Mª­ß××רØxóæMc!¦Ž!‰“’’0?üÓO?Ù=¿m@Òc :...>>/pžaVë@‡c±waa¡¦d#(¶Ý l"‡«ÿö·¿õ´õc\‡vûçëWn·Ô÷”U^Í+íÈ*lsä¶$f5ÅÊ´äÚèó®cq•‡N•ï. Š( Àö˜È}²/{mPƪi˶§,†ávõ@a˜s#* ZLIÁ8'Ik8•uñ\nKNŽKT]ÍÃåpÑÛ?]·Ÿ@… s ò—ðþä/A±íqç'(¶½šÆØ¨7€÷_š 2— È_‚ (¶)¶ ßäÅ6œý¿úWÿŠ‹Ç~bÁ‚Ç's ‚Ì% Â7ùK±M±MPl»AÈ~ø­ìÏBd.Aä/¥ïÚµKÄðøŸŸ Ø¦Ø&îÜÃP‚ s ‚ðMþòW:APl»AlÞ¼œÅæ=>ølAæAþòW:APl»AÔÔÔgñ‡ È\‚ È_þJ'Šm7ûÑs3‚ÆåcÁ†Øå-™Kd®÷ñ— È_Šm‚ Øv?>ýôSÜÌþð‡¡*qoú–Ì%2×ËøKä/Å6APl»W®\ùÍo~ƒûÁæ vêAæáÃü% ‚ (¶G ¹¹¹¸ŸQóúA¹A¿A±MÛÛº“!÷G!ÁñãÇíW&s ‚Ì% bÂð× ‚øÿÙ»ME¢0à©7˜èÎ LÐc ‚¤7À¾@B€JÒÝÖ²kgvwÖÖÜßÉõ9®ãþù®9ç Ù.±ê‡œ×‚Mbãñø¿’ ’+¿ ¿€fû÷€ãOã8ÎãÙét\’ È/ Ù*¸‰§ñB8€äò h¶ÿÑ[=qÛBÃ'BȃY|«§ä‚äÊ/È/ Ùþiš6žz½^¾ðÛTF½}y*,“\\ùù4ÛœÝEQã©Ûí:¸¢IJ^¯ëýÇ,¹H®ü‚üší÷Xø“$Éçÿû˜ÿä]öØàN‘Ùl6¾=Â~Ôä"¹ò ò h¶ßÀO—ö8Ž ¯>o|GÍét*?Îý~¿\.æ°òšBš¦õ?Sr««9·Û­ä8Çã|>›CÉ•ßשɲ¬ü8×ëÕÊ/ Ùþÿ’$‰¢ÈR¾f8¶Z­ív[8N¿ßÏ¿ï÷{sXIÍt:],›ÍÆJÿÉU³Z­òÏÉdR8Î|>Ï¿/—Ksø"É•_5Y–åŸív»pœÝn×l6ƒ9”_@³ý~øÊ¾@(DaÇwà.ˆE¢‹"")H´€A(ˆ…¥ ‚ `$ŠD%P"%Q €sc Â÷ú Ƽ\.¾ôXÑn·)ær91Š»Ýîñññ[áç燼T*@Ã0ÄhYÖóTêº.}3R™L& Þáp8Ð z½^©§R)êƒÁ€—Ífóxƒå¥ÑhP¡K#\¶?|}}ÑéKû¨Íf“b¡P£¢(×ë5/ßßßT,Ëb¯Ùl–¦¯Óéˆñ~¿S´Ùlb¬Õj5MãEUU*¦i2x‡ÙlF3‰D¤žH$¨Çc^ŽÇ£t-ïv»T2™ \¶á“]¯W:z»Ý.uÚ8¥NÛ§b ‡ÃÅ…s·ÛMå|>³×€xŸ—ÞºËå2{¨×ë4ƒ¥RIê¡Pˆúr¹”ÖUþþþxÙï÷T|>\¶?ôz=:út:-uMÓ¨W«U1&“IŠÃáPúwY¿ßgðZ¿¿¿4}·Ûþ+Üï÷ÿ³w‘EQÆ !BT4’$Q"‚$H$AA”BBH%QJ P($! €†(&ºûg¹®sÛÜyø~€oìxfîôÞ9fÕâÄÄ„/;;;¦HinnN× ŽÜ¦ õ»»;_´G@¥¦¦Æ—··7•ºº:à°?°ÏfOOO›®ŸÛã»LGFFŽŽ|™œœTÙÞÞv (—˺ôª««M¿½½Uïèèãáá¡âèè¨/ggg*.!fnÂÞÞÞ¯w¬èW³øKÚ÷÷·/Ú!¢òùùé¶‘[ zë×ÖÖL×ñ[}kk+ŒcccþËA8yuuÕHèéé)¾]\ŠÅâß}~a<==UÔ}(¾hÌ¡J¡PpÒ±ÏfëékÓ›››ýŠM3‹´\.û¢Ek LÛÈ»ññq½õ»»»ñ ã¸k˜™~¼±±¡2;;ë ùIºôººº~q¬Í^a¼¼¼Tìëë3#—\%hmmÕ5¨`¦766ª¿¼¼„1Ë2ÅR©d¦‹Eà°[èííÕ[¯ïâ¿ÞávppÆ™™ÅÍÍM_ôÌí© ø×îŸóósõÁÁÁ0^__›“¹Vý©hퟫµµµºßßßM¯¯¯W}}OàÏÏϾ ©;‡í܂ƙê­||ô%ü ?99 ãüü¼âúúºY@ÒÓÓã*`”±y8<<FÝ4/ȲÌ|§OÀÇLJ®>·]DcÏâC¸>©ÍŸÁµ\À>êà°|þ¸®~ÓûûûÕ/..¸¸¸hð~xxPikksÒ1ÛŒ2o61Ë{ušå~Óýý½–ŽÍºúZZZ\DSÇõÒ××WÛÛÛ͈ò•••ååeà°OøÏúîîn½¤çBèAhŠKKK¾”J%•,Ë€„t¹.½ýý}Ó5g!Þé¥)JŠMMMñ#$WWW@f¶‚f¤¹HUU•^úùù cgg§âÍÍYž?55Å&þ°_G5€ K*Z‘#øèл ßûGÆ6‹/5.w ÷‹û0¶½|¼|\..÷‹ûŒm‘Pœ;tDq5QÀØ ÅÑÅQÅc{ÅÑÅÕDqc[¤3GGGMÅŒm‘ª*3#6{gàbSúÿñùTU©JU*•J¥”Ú””$I’M""Ú‘Ÿ Y;e’ ,‘°`ö–EðØ~¯æÓ¾³çÜ{föê;Ý;û~UÓ™ç>çÜsîÓ»÷ó<çó|ž/Ú´iÓ¼yóÎ;7®ªªª¦¦&QsÓ¦Msëxüø± œ:u*êTWW«vîÜ9xðà:ð|QïÞ½+**žìÒ¥KYV¬XA±xñb 3niÕªU‰oܰaCY&&Lx÷î]ö/sàÀ²ú8pàëׯ ÛŒîÝ»gË7V®•kå6q¬_ë×ú5Æx°íF‡.?cæ{ôèÑ .,//gþ[å“'O~ÿþ}œrùòå(ÄÂs^ÿùóçQ¡E‹>|ˆÂž={Fa»vífΜ¹råÊ©S§vïÞ]_±k×®´åsŸýMË–-)Æ {óæMÚò©ÉeŽéèž´–Ïwq®H\§cÇŽoß¾µåçÆX¹V®•k¬_ë×ú5Æx°íF;vlüKtÙþýû5™öæ£ôl:…Ͱ|qóæMfî£Bmmm¶å'.xäÈ‘‚-ˆÍ‹ óæÍËY¥eú•nùteîܹ£ †îÔï¿ÿÎJ<ë¢IbåZ¹Æúµ~­_cLiàÁ¶髯¾ŠãE‹eÔ—…oܸ1J=z%dsÉÉÖ¾}{’ý% #".Á¾}ûÚÔAª•z-?QaÚ´i ±üõë×ǧXï§X¾|Ô¨Q*„ëׯÓq‰Žý'âèô:"Ãò9?~|Ìý­[·&’PAzýû÷çgÉ4Ø­[7>2dHü{îܹ=zè:\“ž={f]X¹V®•k¬_ë×ú5Æ46l»‘0˜°¨˜öÎHp§Lš4)ÝH¤•õ.[¶L…ØXNœ81{ÍU¶å§;8_†åkÖùóÏ?Oïß¿ÿ)–æÌ™¨À×}œè5âë :T›¶|^&Ä»:,±‹âñøWðŒQN~Èg[–"^‰ðþÁº°r­\+×X¿Ö¯õkŒi<<Øv#±‡R³d×ÿã?¢fŸ>}TH¢TY{ÎÉxÌ&mQÑÃ`º oöä(Øò!²È°”+aùëÖ­Ã ,œKÑ-H¬d+ÌòÙž„÷ Q˜±(¤Ç#ݽ{7Kéè!‘7UkÛòYþ‚ ô¾xñ‚ùèÑ£$€‰B&ì•G×¼UˆòÛ·oÇ\{Ì©ª÷çŸrµÊÊʨ°|ùòÆÓ…±r­\+×X¿Ö¯õkŒñ`Û$¯bûÍzOÁN"©J˜’Ie\*=íMT•¥à²|;˱èü[ËW>U\Éò3 ØŒjõZ¾Ò½þßGp“ÊÈ ìü™ˆÓã§P' fô{õê·—¶ü¾}ûêý€8vì˜2Ä*#Žr؈È£HÂhââ8³QØ©S§ÆÓ…±r­\+×X¿Ö¯õkŒñ`Ûtþüym.Rï)¬‰Òb0&&›å»Û¶mË9?ÍÄ0ý†²„u¨D-¦*x·Ï®]»Æ7=éE‰Ø¾}»ö;MX¾ââ(ŒytÓG5䢄Ù÷(¡¾‰%zÑ!ã/TÊYâèbÚ¾ñta¬\+×Ê5Ö¯õkýc<Øv#á œ_'kHÔ0`€ M8¢ü»ï¾S$[C–¢=~üxïÞ½„–ÉþñÍú·ó뜕½rŒè2‚ĘŠÎÞð3=¿NMÁO¤ ?AySèë(]ÍÄ¢Ì4k×®M[¾ éªU«ÆŒCw$Âó–ÿðáÃD$ÞŒ3)dYÑ—xeADÞØº0V®•kåë×úµ~1l»‘4/‹™e׿páB"©f— ²ÒÚ3E²eÛjz Mf¬ãÄŠŠŠz-_“ÇaÀt2,_0#®îÇ…­#üO»}rÛÚ$6kÉiù×®]S·@ÄCÉò’jœ’ë ÷qìý+豯I£êÂX¹V®•k¬_ë×ú5Æx°íFbYQf–QŸ%I‰ H„’v25.Óeù“*ÛŠ´©cÏž=ùvÈT.ÐZ>ލü%Ù–/´Û ^[pNÔo¿ý6*ìß¿ŸÉÃqð÷y s¶|’©„sÇÒ»9sæðD<,ÓíiË×¢;ÂØ‚¨ ‚kòÖb„ mÛ¶•ësLϬñta¬\+×Ê5Ö¯õkýc<Øv#iUÒˆ#òU&æ-&nY<¦](Å•+Wâ ˜tD²1ãŽÇäÜ,„éäì•i\¡–¯-1ÝZ>×$[þÁƒ£)ac‘ø—elé@î ^½z•¶|’—Æ¿dFÕ)ÚJDŽžÈIË$zô±h®¯Ÿ—oùå—_T?¢ìÔŸ»zõjãéÂX¹V®•k¬_ë×ú5Æx°íFÂ6”곪ª*§ß³J**¬^½:]AI;å…-¥ëÄ·;—Ón•wdîܹ ±|f£µ^K…Ù–Ï|JßâSvûÔÆ§l ¢ÎJxðû÷ï£$±¿î›¶ü5kÖ$’¯„ó¥-X Él€ƒQ£F¥{!<£ õrQNþ›FÕ…±r­\+×X¿Ö¯õkŒñ`Û$§„aÆ8q‚ùZÊñfbÏ´Ú _g±åiV®\IÁŒ{º™H”Däðáú}"µ(ŒOùvY¾Ò~ú\òèahùVÚò¹* ÊƦŽKÁ–¯®w%\P©eYÁ¥Ô¦ñR‚\29wûÔ92Î"± ÙntŸ[¶lÑ—êtQ]]ýq¢%Ñ!ž- éú%Ê™žol]+×ʵrõkýZ¿Æ¶ÝHL‡?åcèСRF‚SÕÌÈøÂª0U’iJ>X¾|yz’4ê:0Õ­ú²ül-Z¤@»Â,Ÿ¬'QA^Ža³ôKwEÊ- ãWU–ׄåcÃz³ÁYä¹Ñô?gEa$A•…«cÄõÓKût:¿3‘~\D‘ÒÖ…±r­ÜÒÅX¿Ö¯1Æx°íFbqQ,4J€--]ºTÕ2ì\sÛéOeZL–‡o%૱[šiN;=½ œ›~†*'r™ù.–ÌÒ8ÍIgÀ||:–,‘[UWV6úC2]Q^^N[:äLû‚t§ÎA€U³Ýï"°ù7íëšÚшÙô¼XàUFiëÂX¹Vn©c¬_ë×c<Øv#‘P„„•••dþÄ¢Ò¶úéð¬•"Rkþüùì̱{÷ne(-ujkkI”ÊCmݺµÞ‡R,ý~p62Á¶?~eÁº¯˜‰Owƒø¢œW«©©!þ×ÜÉQÙ.ź°r­\+× Ö¯õkŒ1l»‘L‘Bø­F¾·¸•k¬\cýë×Süx°íF2E q$ÎaÊ|¸ž7ƶÝH/^ŒòãÇ7¾å_ºt Ó*Ëźuëþƒm4þ|ž}øðá³ ÇtÍ™tO×¼qãŸÂÚµk­‹bÆÊµrÿúë/zê¦i×®ÝË—/­Ü¢Åúµ~™iß¾=…i,Xðïœ×c<ضåøðB`êýz?ÄbÉï§OŸ~ìØ±³gÏ»%Xݽ{÷þkmÔµkWž}Û¶m¯^½šã¾}û&ê¼~ýz÷îÝ­[·.‰Á¶±r­ÜÅ‹kh½iÓ&Úhß¾}zK6iÒ$+·h±~­ß~ýúQ_|ñÅÞ½{úé'æÎ¢rùòeë×ãÁ¶i¸å×ïa2 êû÷ï§ßH×»f/üñãÇüÛ§OŽ1þož8·2áÁvÑcåZ¹ŠJåoTÐYQ|£•[„X¿Ö/¿dŒ«GÅ¿âÇŒ³ªªªr·¸1Æx°íFêÙ³§o°†îgÏžuêÔ©cÇŽLx«&\¿~ùÝ-ZÄä7 †åFÁ©S§¸kÀxõ:vìØ¸,Χ ¾üò˨#V_!Êû÷ïŸýD,0ëÝ»wLÒ³€jÉ’%wîÜéY‡2¾ 2„»Z³f }šxLüsú AƒTL›6ò#FÄ¿„Þñ‹•——×ÔÔ`ÉúU¹+M{gôŽÕÁ’ÎX ÿ†ÁseŽI™£8Ãl+×Ê¥ל:ujâ ³gÏŽëµr‹ë×úÕ´ÈÑ£G§çÖµõkŒñ`Û$äLwI¯‹äœá@ †ª?šèÅùâ Ûò ÓŠ,Aé¼ ”+Ž+kz>…üûîÝ»Q­C‡Ñ{ˆrYþóçÏ»téR– "Ĩ %|ª$)'*IA"€M¦~Ó«W¯pwzвüp¸‚3¬(ˆ  ËW(²¨S]]ýñ’6n&mùéuhã>Z˜åG§:@#ʉ¦Ë~ðÚÚÚ¨$Bã8¦C¦ l—:V®•+¨ÌèíYñ+×X¿Öï¹sçô?š†|iv^cŒÛ¦pËì ñïĉçnß¾=>"K–Sõ‰ì#ü®™3û _QJ:’Ÿ0æôÒ2å´| RIS€jTc~:_g‚ñ,_û”ªc¤IwfÄæ±ÒŒcïÅYx°mš’r­\` ˆv`tÁ[üÊ5Ö¯õ{òäɨ "àW-\¿ÆãÁ¶-_SÑ„WMü'1ï®ñž,?²y‰ôbª#GŽP.ð*z šç@³Å9ÁŒ£æ¬Y³Ò½Øœ–Oè]"ÉJ|Qâtmûü2X~ºßL¤h„¥e·Nü˜‹-â8" ™bçØƒmÓd”k廫U¬@þ'†:%¡\cýZ¿,Û&`×®]$xÓÂ{î¡pýcŒÛ¶üì$"šÜ•å‘lÙ–øða}JS¥K‰)$P‰2–ZEå7¦³¤æ´|%/  PU"èm(õh†å“B&mùËWæ’É“'“äS®‰Ç(I–?|øðØ­äP"QJN6lØÀ¹‘…Ä¡ÜÕ™3gðé(¬×òé(ÄÖ <‰'”¿”wq:Ï’ðì™3gRµEJÚò–F!·¹g¨ÏË„(LóöíÛï9îw¶MP®•Kˆ©¶/>”áE¨\cýZ¿Šçg¢áÖ­[QȳóhÞºÏãÁvý¸‘4}΄¯¤-«ãŒ–âs¬¹Ò)ä×-Ìòã"$™&&•éj¨¦<¸^Ët)(—‰²@KaœªÝ¿_åè8ÃòŸTO)^•Ç•.H€{€ßï8p­|î'GÍ•8ú«¿Žm!ýI˲üüõ{ã–ey÷¾~µbå#GÍ•8úè/€c[Ho`Û¶q‡axþÔÂ;$ŽæJiê¯ÄÛGŽHi"qÀ±-$$Ž‘8ÒDâÀÛ|ð/h.š‹þ¢¿€cÛ±måc壹è/ú àØæiš†”§i:‹ã8Œ­ëúÛ@]×a mÛ—¯UU…צià ó<‡N%Ir>Ö÷}˲ìd&Š¢0³ïûË×Çã^¯ý(Š"4«ëºó±<ÏÃØç{çdY’…á˜Bô mÛ¶mÛvu¡mFWOÛ¶mEWÕLµQmÛ6kÚÞý#n`ðîÉÓó0‹ÿ[o~‹ÉŒœwϽ™ÿY·ÎN˜6m‡£C‡ÅhŸ>}þE!„Å6ñ|øph}ûöœråÊÁùõ×_Ž.Y²D¸õ­„"ç˜È‘ ×®]³.^¼í9í„ìÙ³;ü6N!„Å6q/uëÖÅ#ËTÖÐñ ZòäÉG¾6råÊå’LcBȧOŸ°›¼¼¼Œæ Aƒ`Vc‰oܸ!k'Ož„†v»‚cõÉ“'ЬY3 .ä´'!û÷ïÇnÊŸ?¿òªÈĉ§E‹³¸u‹$nܸœvB\B°­PrÍèѣˡåoÞ¼ðã?Ú VÆáˆ#8í„ÂbÛ£C•zY8púÉŸ¿zôèaÔ¨QœvB”Èy„5kÖ4š~~~0g̘!8:t»ˆY¢ÀÙuÎØMÆ S~@[±b…à «\þoCW!¦BÐô { Àd ´¡á㶬Ŏ[¸×½}ûvÉç„BXl»²~ýz¬/‚ˆ•f­ZµçéÓ§rF ¢P! •3Oœ„ A™x„£æ0±…gÈ!p  §†„„pæ q Q£F•ob[@€-Z4YCV"4Ä’;=wîF3dÈÀi'„ÛžƒL™2ëëïïo4­Ch5œ×¯_Ãùé§Ÿì„ãÇË)k„%hÄõ»ÎØ8b쀔&ùЇ•f<þ|Î~üXOˆ^!ÐÐ7Äáè³gÏ03fLÎ!„°Øöq)X_D§M5‡Ù¿Y‹/ž\K[g_Ñ‘ÛN0BÁÍLåT9sfã6G|šÜµ{ëÖ­ð@ÏÉ'ÎC’ y p2&ÚÈZÕªU¡mÞ¼ÙN¨Q£Æï‚ !„°Øv?_Æ4i¨e6ÌŸþYÖ’%K&¢tꆀ6$œ|B48ßÈP!£ ¾à S€ÜÛïôéÓ²dÉÂÉ'zˆÜÙ%·Ñ!„°ØöG5?áˆ)†Œ`²–/_>h‡¶pB¿~ýì#„Î;c?^[äÕ«W‚sêÔ)8xY&8‰'†sçÎÎ?QBäS`hf4·lÙ³J•*²†ëßòé3+—¡zõêœ|Ba±M\ŒÐì§eË–V!#²XÖpÔ Ž½Ù ³f͂жm[;Á!¤nݺØG+W®ÔÈ>>>ÑxOppõظ–+W.8G „¨Q£*SÖ­[³víÚ²6`À9W9ä¿;½B!„Ŷ›!ÁÁÁš€q‹Zµji‚LË•+'÷Û¸q#„jÕªÙ F!… vüV˦¹=êmYC¨!´¤I“ âÓà„„„ŽBHdd$¶êm¼|ùrM@ðaàõíÛ×N@‡mè¶Íù'„Ûž€àî–>›ÔzÎ •5TÑr÷¼\7«BDR¦Li ·xýúµ¦#÷“'O¬ü3cÓüùóÇ!§Çõ­ûy¦9ƒ6aÂh]ºt±Þ¾} !J”(œBa±í î€aq7mÚ¤‘ѲËJsÑtY½zµpíÚ5(ì#„___ì£wïÞMä¢YU´¦&ÿñǧW¯^p†.8F!ø%Õ·îÃÝ+M°ÙÌ™3Z̘1á  —€BXl»’3gNý L|‹†|àÀYkÖ¬´Å‹Û Hi2>ÓBˆÜ…+nܸ¿ £û—¬}ùòš———à ²ÙÇ!¿°•ÐýK#Ož<rÇŽe ?»Ðð,83f„sîÜ9.!„°Øv;ëX܇jä9r@>qℬµk×ÚìÙ³ †!„`beÏž]#[gIR§Nm4q¾æû÷ïíä#*+BˆÀ˜1c°•®—}þÖ¬Y­N:ÆjÛ·oçB‹m÷Bp+‹Ã¨J?}úôð/^¼(kxû oâÏýp®\¹"8„¹b42¾bAΜ9³ÑŒ#Ì/^Ø Û¶mƒPªT).qÒµkWl%TÑyèСš(S$B«\¹²ààMÙﺊBa±í6jÝoº;÷XsöŸ¬áIÞÞÞp>|ø 8„4ýÂ>B0Œn^ÑÙKÖN:-[¶l†.bVˆ!„Ûn…षÐbÓjèãDz†óiÆÿÚÀ æ*wæ}è¯¼à£æÆöH5‡sûömÁ„W¥„úûûCž>}ºæjXÚ´i',, N¹r帄Âb›¸ çïn}úô ²Ñœ6mÌÀÀ@¹‘‰ìBråÊ…täȼaÃÈ5kÖ4š¸TsïÞ½rA.ÿOBd"##±‰Po+}¤3ÀŸ7ož¬Ý»wZâĉU !„°Øv+¤nݺXÙ•+Wjd4ÇV>àf›6mgÕªUpêÕ«'8„;$H€„gk¼bÅ e¿®²eË œJ•*ÁAºàBpz›'É•~“&M4ijÏŸ?‡+V,Áyðà$°p!„Ŷ{!LrøKFŠ/žò*8gçÎpŠ/.8!„à*¶îN+}ë–f‹-ŒfµjÕ`nÞ¼YpZ¶l©ùÈF‘c‘öMoÆÑF[ÖÐ!ºåËÚwß}íóçÏ\Ba±íFH²dɰ²×¯_×ȸ¢ ÿ£¹nÝ:˜uêÔ16þ͘1£à8„‚ö{ÊÍh$Bø~~~F‡M`âà‰1yøðá‚CÀ7jåa‹êÕ«+3¼¼¼Œ…t¢D‰àܽ{— A!,¶ÝÁ¯²&ðÌâÒ¥KÓ§Oo4CBB`"ÀIpž>}*Ÿv#„H­¼¬?:&Nœ F³yóæ0.\(8ãLJөS'Á!„Œ3æ›ÒI+T¨ÿ—_~Q殽|ùÒø`å Ba±í&ÞjcYqóS飧ˆ2Ueûöí0Ë”)#kÈZû „!8MнS«V-¥ö¼ð{õêe4ñõÛØ“oùòårË@BˆL×®]±‰Pr+ý’%KÂÇõ+£‰«^0=zÄØBa±ýOB:„eE°°Ò?xð òcZDDLÄËò÷˜4iÒ7…ù£ÇüAƒéÛùߦáé_p!8@.žÙ¬àH‹ÑL‘"Ì7ncæÎË… „Û_¿ËŠ<$¥¿k×.e  §ÁÌ“'¬ñ$!.¼5Ý·o_¥ß§O£yöìY8™2eBˆ~I±‰“¦ô­~{ÇŽ3šHByþüyã6:t(‚BXl» 2eÊ,«¿¿¿Ò ƒ›cFÓzÏ’%‹æZhh(ׂ|¤Y³fÒÍj›3«è¨¯ü>pà@Áyòä œØ±c !DM¿°‰ÐLégÍšþ™3g”e9ÞbC‚‚‚¸„ÂbÛyˆkÞmoذ~Íš5æÕ«Wa¦I“FÅ„¦D\ BþÍÞ@ÄúDQ§%*%E!@"ˆHA*¤JH¨BP…JJ¢‚ @DRA Q$%j¡$ªª„v9ÿ0s¿¿ýx8?gÀgÞëîÌÜICCƒ›†m1<<ÌüÚÚB–——™WÃ…˜ˆ¸6fŸŸŸ‘Šód2‰>à NôÜÞÞf†ãÄ ""*¶%ÖÃ1{­Ë®H–Q%®õŸdÃkllŒ±¥¥%ˆˆ™»)Ê+$°´LÆv^x䥆 "1ùøøàöa½ ³²²2.yxx@Hss3“ÇÇÇÁGaõõõÛÿŽmll0?00/7Ö«¸¸Ø>ûDDì ¸wÞÞÞ`ÓÛÛkìÆ´¾¾ÎäÐмؑ±³³3ˆHD¼=îæhqn—>2SZZ 1ÛÚÚr7½êêêü ŠþµTò+++ŒŒŒ@Dœ(£øXrÃ&•J1Ï0à(KçÑÚÚZ÷o‚ˆˆ¨Ø«HC³›šš`6::jÿû ¤¤„á———àYYY³ÅÅEn6ó‡Yuu5—œŸŸ#äôô”ÉššËl‚žžˆHD¼@nlXhoƒâÌÌÌ0<;; ¯ŽŽÆvww!""*¶%ãøØ’ß´¿¿6îrÚêêªqN‰e2;–»š\D,xžÌ]óe˜UVVr ï³ äòòÒ=î°wx;nnÞ"Íëë+óEEEöã&&&àÅ^§î¶¹ˆˆ¨Ø– ›››ã7ššEÕË*ÝÞê<™L«¢¢‚±ëëkˆˆMww7wÍÎÎÌ8ãDzéîîÎÒ}S ã¸oˆHn?²Ó!lžžž˜ÿ½;€ˆ&Š¢,„€¢T” IRJ¤¤PR(P@R„ P¢B*@$…T* TRJ$‘ª@‚TAç? ˜=ÃúÁùÜãÙ½óÞ»';;‚™™÷÷÷«ÿÌÌÌÍvÂY__ßéÜÜdzT/•••);i¼Ê2î’Acf555Q/[æææ*'Mèåå…•¬W²ôÓÒÒ‘™1·/RÈÓÓëóòò £òbeffæf;:¢€677! ®x1‚ªª*ŸŸŸ#Twww,TafüÏÍUóððY0CáýýñðN+ÓÓÓOrr2+~~ 33f\GÍÉ¿»»ÓÓþ–——•ŠüõgYkk+ÌÌÌÍvÂYyy9ßéÅÅdLâ#;;;Ô×׳øèè¡xÔeÓÓÓИYÐå~CÆtq'¹»b'““ÃJî„#:3çäGM)--…`}}ÅuvvÆ2ŽN„™™¹ÙN8ãÎßéëë+d<ò­Ïtijjbñþþ>B1HLÏî6³··7.™ŒŒ Èb¹÷¿¿¿ˆ‡A¾¬d¨/⩬¬ 9½bf‰.Ƚ1ÞÛÛcqss³ra„ŸÌ`ffn¶˸'ÆÊý1DQ]]ͧNNN hkkcñÖÖB-..êׯÌìêê*6-\ô÷÷ÇG’’’Û™ó*Jl‹ÌŒsO¸p˜þÙññ1©­­…àððÅuuuÅËî6337Û‰d÷÷÷|¡ùùùˆ‚ÿïùÔõõ5,^[[C¨ –±3‡À̶··¹dx§²¯¯/>’’’éÌ9o–*ñœÆ3“MNNrá EÝ ohhˆ¾ îèM337ÛößèŸÉcŠŠŠô´’žž/--!Ôéé)Ë8M 3Kô á>’šš Mff¦rÇddd„eããã03Ùàà [nÈvwwùHKK 777,f¬&â))) BCüRÌÌÜl›JŸVÚÕÕ…è3ŸŸŸ!èííe1O‰#'*ë{ìf666Æ%3:: Ûf>’•• ×#ë™6„Pœk‹ó53sáðW²àX{{;,.((@<Áh¿337Û–HáÇØBÒƒ8Ÿ aÌøìì,B}~~ê\Í,øŒ5??ÛæHŸ´Š‹‹Y{{‹P+++Q¿Ù™£:ôQ£ÕÕÕ`­é×x>ñ0,8€æ—bfæfÛi``€/tjj 2ý&g`xx˜ÅìêC†BB‰ÌLKÒËk ÐTTT°þòò¡Ø-Dªlf………ú…¬ûa>ÂËYðÇ”ÅÿØ; àªÒ6ë.Ü÷àÜîâÁÝxpwo:¸»KpwøZù‘v·Ü}æ-¨)ᾩ/wÎ…³Wíö;UOåY}Ìü¾öØ4ÿÃÝâ×ô;BH¶/D„ùH”Ü9sgûõµ)ÇÕ­ ª_×c³|¡BÀöî]Þ®£ñï‰áUj+ ¬ïÔÞþC6uéT/ZÔ²_¯d `U‡à7×2ºvüŠ6¯á}'Ù4}¿â ‰ï:hØÁ¦¼~ê gÎ\›áÁq@§=ߺ¢ÙïB²-ÙVÎ÷ræÈaÙÒ SÇßc³î«Í~e‡ íë6H¶•Sá}ö÷înß_Û1¨]¢¸e¿I™ÒÀâà€7׎ôí ΓG²íU$ÛJt§¡@H“.–ý\9së¦ì~smpq@˺n—m!„lÿÇOœò§wo… °ì/6˜< Þc³OûàЊåoˡоþv ¯rykÔ¬™e¿GP p|ÍjͼyòñàÞ;<¼’íïþß/ÎFIO˜Œ<Ú²_¤pà³/ß\Û»å Ð&ð-:ï¦l !$Û’måÇkW€’ÅŠYö×&'££"=6‡÷ Ö§$k_÷’måìÆ @ç¶m,ûý:wö-]â±éW¶,ðù¹3^ï!ÙV§¦ãFL´ì—.Ux|ãã7×.ž¸ø×¬-ÙB$ÛÎFù2ó`vkËþ³gƒCûzl&¤­}ÝH¶•£«W½C‚-ûq½zÛæÍõØl^¯p{÷. ¯÷l+SÇϦŒ›nÙ¯ìW¸uáÁ›kÞ~ /V\²-„H¶òôäq fåÊ–ý]‹1=º{l®Nœ Œ‰ŠÔ¾î $ÛŠ9G ôïÒÙ²ÿúb“ ©)–œ[½JÃë=$ÛÊø‘“€„)É–}s²¸tòºÇf®\¹€/>þN²-„pɶd[yrèРVM˾¹ëØÑÂæÊUíëÞ@²­lŸ?0ç«-ûbc€3¦{l 6¥§ix½‡d[9x46s¶e¿qƒ&Àéƒç=6Ë•-Ü»òD²-„pɶd[1WŠ-Ô·ìŸ\·èà±yiË@`³¦Ú×½d[Ù”ž ·ìÏ2˜?q‚Çf°¡Àœqc5¼ÞC²­ Ž ÌK]hÙoÝ¢ phçq͆õ§Œ–K¶…"Ù–l+—·díÆ>xhß²¥ÇæÇÇŽþU«h_÷’måõc££-ûé£G©£Fzl®œ9ãÕgŽÒðzɶ,™»Â²ØصyŸÇf§ÎÀÖ ;%ÛB'‘lK¶•3×]Ú¶µìߨ±hÛ¸‘ÇæÏׯÅŠѾî $ÛÊâ)“©ƒZöNžL<ÈcsÏ’E¯ï×ðzɶҿo$°jÑ:Ë~÷Î=Ík¶ylÆôÏY.Ùv!„d;wîÜÀ?ÿó?k_wmެZ˜wb[öìß 4­SǦœ'wnà/½ð¶^íë’mÅ\æ $nÙ_•0í±y)C÷€xɶҧG(°aÅfË~Xï~Àš%<6'ŽžL›0ÓͲ-„Fr#¼ŽÉvÁ‚¿ýÛ¿Õ¾îÚì^¼ˆìÖÕ²ÿÑÑ#@ÝêÕmÊÊ”¾8Nûz¶#ÙVŒfF¹³t÷Ðð0Û{@ªè/"ÙVºuêd¬ÛžµËÎ-ÎW›ûÀ1CÜ,ÛBa$0Âë˜l+V øó?ÿsíë®MÆœÙÀÀ¾},ûÏÏœªùU´)7©S¸·wöõlG²­˜ Ès1¹eÇ‚y@lÏ›¿Ü¸-RX²í=$ÛJ‡ ŽÀÎÍ{-ûCŒf'Í÷Ø|õÀ\vîfÙB#¹€^Çd»L™2Ào¿ý¦}ݵY—œŒŠˆ°ìs1(_º´M¹k»v€y€¹öõlG²­Œ‰V'Ì´ìX¾ëÔѦœ7Oà/îßÕðz ɶÐ&Ø¿íˆe܈ @âÔÍ£{NÍ›´p³l !„‘\ lÙ²ŽÉv¥J•€ï¿ÿ^ûºk³lÚT`R|œeÿõ)¯E‹Ú”ôî ˜“çÚ׳ɶ2,<0‡[¿·oå{ûL*•+¼<{FÃë%$ÛJËf­#Æ–}s60iìTÍ›™÷€Ê~UÜ,ÛBa$0Âë˜lרQøòË/µ¯»6sÇÌku-ûvïP0~›ò´Aƒ€“&j_Ïv$ÛJ|¯žÀ¶ùó²ôÞ¾–-lÊÍë×nïÞ©áõ’m¥qƒ&ÀéC™–ý”³€QCÇzl>{ü%P 7˶BÉŒð:&ÛuëÖž={¦}ݵI9˜5vŒeÿïž<ræÌiS^2u 0y@¼öõlG²­˜Wsû–.±ìßܹhݨ¡M¹gPptõJ ¯—l+uýëŽ_µìÏO[ ŠbS.T¨0ðôÁK×ʶBÉŒð:&Û7>þøcí믣g,ÙßÌùWï{ln›oû@&íëYE²­ô ~åë,ûìÕö·) 6¦¥jx½„d[©Q­&píìmËþò«Èð›rÕ*Õ^}ò;®•m!„0’ áuL¶[µj<|øPûºk36: X8ÓþCÞ+\øýöMÍ37Ú´Ö¾žíH¶•ÎmÛg7n°ìzü(à_µŠM9qø0`öØ1^/!ÙV*U¬ܹôвoÞÈ ˜·sÛ”[6o Úyܵ²-„=Œð:&ÛÁÁÁÀ7\»¯+¯Ï_½Ÿžfÿ!eJ”~¸rÉòLZCÿZÚ׳ɶÔ¬pyk†eÿósgóä3›òÊ„À˜è( ¯—l+eK—]ÿز¿uÃN s‡®6åž]{ÆÏ]+ÛBa$0Âë˜l‡‡‡ÇŽ{»öuóÙ¥Ce? ¡Usû)S° °»g7Í}½»ÅóçwÉÁ”lÿ_¯R§Dq`MÇËþÁ>=€bùòÙ”SÚ´‚ü*hx%ÛÿMв'J¡ü…åã2,û“"’:UØ”Û7í Dvä’ƒ)©BüwŒäFx“í#FnÞו̈°Óá}ìû~E ÛºwöØ<ß?È‘íëÞ@²­dö=Þײ|<¬7P wn›ò²@ A©’^ï!ÙV6LÛ»nÊnËòô˜9@õ þ6å¾Q@·V}]+ÛBa$0Âë˜l'$$K–,y÷u]DêTÖª<>tÀ¦\²X1Ëkν]ŪáUþæÑ w®\6åOŽjU©lSÖðºM¶u¸#9wôP¿n›ò²y+Èðèwì Ø_‚.„‹/Œð:&ÛK—.fΜ©}Ý>JËõ;{vÙ”ëV¯üáðAí뎣áUrçÎ üõ£›¿Ü¸¼W¸°dÛGl+æ¹å€y†¹MyǦ=@û Ž®•m!„0’ áuL¶·nÝ 6Lûº’ÕÇ2]ٺŦÒ¢¹y“öuÇÑð*E Ù¾JÀ$_Þ¼ÀŸß»£áõ$Ûʽ+ å+ڔϾøú4¸ke[!ŒäFx“í'NaaaÚ׳½phÓ›rd×®À®E µ¯;ކW)]¢ð½Ým•Ë—^œ=­áõ$ÛÊGwž%Š—´)?¼ö!P¦tY×ʶB„††Fx“í[·nAAAÚ×í£ô Ž®^eS,Ÿ1]ûºÓhxãÏå—çÎØ”[Ô¯ÜÚµCÃë H¶•çO¾ (hSþúÓ9r¸V¶…ÂH.póæMÇdûéÓ§@½zõ´¯ÛG‰èÚØ·t±Myîøq@°¡Ú×GëøW­ ˜‡ŸÙ”{GV­Ôðú’må›§?eÉŸK–(<¹ù‰;e[!ŒäFx“í_~ù([¶¬öuû(z÷¶Í›kSÞ”ž Õ¾î8^¥qíÚÀƒûlÊCÃÀi)^A²­äË›xùá76å:þuÌc—Ý)ÛBa$0Âë˜lòæÍ üÝßýöuË(Ãû÷{µ‚§Ú”ÍÕæ@Ïà í뎣áUZ7jÜØ±Ý¦œ4|80kì ¯ ÙVоW øäÞ3›rP»`÷û](ÛBaôÈ“'eß[²]«V-àùóçÚ×ûÛ°WΜaS¾µk'`nþÔ¾î8^¥}Ë–@ææ÷mÊ«fc¢"5¼>‚d[)W¦ðàÚ‡6å~}#€ ׸P¶…Âè-`T×aÙîܹ3páÂíë–Q¦,š<ɦüâÌiÀ<–Iûºãhx•îÀ‰µklÊû–.Â;uÒðú’m¥jåjÀówmÊ£‡§¦ºP¶…"330ªë°l>ؼy³öuË(©£FÚ_\úg÷îòåÓ¾î8^Ř3°ÙR›òå­@@Ó&^A²­Ôõ¯\8~Ŧœ–06p¤ e[!ŒÞFu–íùóçÉÉÉÚ×-£Ì›0>K/\° ðû­Ú×EëÄöì lŸ?Ϧüéñc@ÍÊ•%Û>‚d[iÚ¨pbÿY›òºe>=B](ÛBaô˜7ožÃ²½{÷n ..Nûºe”eÓ§“Ä[ö«ûùOO×¾î,^eXx¸ýÓ ½y(R¨d[²ýìñ—w.>üòãï%ÛΦm«àÀö#6eSÚ´lçBÙBˆØØXÀ¨®Ã²m^ó h_·Œ².9 aÙoÓ¨pmûVíë΢áUÆÅX?ÝðUò碛A4¼î”í¯?û1ezzõªÕùO$ÛΦcpg`û¦=6å+§o5ªÕt¡l !D»ví£ºËö·ß~ øùùi_·Œ’1g08´¯e¿o‡öÀÁË´¯;†WO7 ,˜4Ѳ_¥|yàÅ™S^Êö³G_„´‘m¥g×ÞÀ¦U6eó†0à½"ï¹P¶…¢bÅŠ€Q]‡eÛ+W.àÿñµ¯ÛDÙµh!ݽ»eDÿ~Àº”$íë΢áURGÒF²ì·lи¹s‡†×…²=eÜt3|üý+O¾øè»“ÎI¶Mÿ¾‘ÀªEk-ûyóæ^þáWɶB±ræÌiÙ÷®lשSøøãµ¯ÛD9´r9Ú±ƒe?yä }Ìhíë΢áUÌ9m`úÁ–ýÞ!ÁÀáU+4¼n“íG×?€Øˆxßy@š5X8k©e¿b?ÀÜoï*ÙB#¶€‘\Ÿíþýû{÷îÕ¾nåÔúu@÷€ËþêÄ`td¤öugÑð*+fÎÆÇÆdéjRS4¼n“íuË7ÀÕ3·|G¶•ƒFé s,ûM6Nì;ã*ÙB#¶@DD„OÈöìÙ³_¿ýË ûºùÀ?2ÊÒ@ q™Ò–ýÔ6-ÀŠÞÐQþÝûhx•ÉÍš=ªUµìÇÖ­ ¬Wç å”í递%JÙ¼úË^ŠþÈ(Ý[‡}¢,ûj4F…N}CGy÷4C‘””Éõ Ù>|ø0ЧOíë6QN‡÷9ß?Ô¾¿ü•œ7(UR‡N²­áu|x3³ÒפлF5:·ÉvDhиAŸ’meÍäYê6êÄt¦Cç*ÙB±Ž9â²ýìÙ3 Zµj.Ø×¸ŠUùäøQÀ¿JŠ·ë*V ¯²oé ¬SG˾ÛòËö€èA@­þÙ ÛÎ]‚®L; 0ϺӡpÕ%èB#¶€‘\Ÿíÿ`ï,`ë:ÓzJ ¸JTn8Q…Šá--•™ÒÚ•&XhËmÈ´Ç ãz4ÆB µËÌ ÍÄa§3<¢Òÿô†§àX÷%ï¾wŽŽàFº–òIŸôc ùû*ûÛßz¯käþôõWoµkç(Œm—7^¾¼t 0dÀG‘m±ýèýÓ ÁÎ {âÛ:cr>0âÆ\Gal‹d!iV­Z%Ó"¶Ï:ë,àwÞñ^O…zܱÇ¿}ÿ]GalÇhyuÓʧ€n§Ÿî(²-¶Ë–“€’ü¹ñm]ô½eÀ\ô_Ž"{b[DBÒ!oÓ(¶sssÅ‹{¯k*<õ„€†ºg…±íòÆÈŸ¿ù:Ð.§­£È¶Øn¬?Ыgo 'çøÕUuÉÜ]ÿcc;^>]þ 0 ßYŽ"{b[DBÒyyyiÛÀ½÷Þë½®©ðÌ^gïüàûŽÂØvyãe›V­€¦wÞrYÛÁš²•ü…>½ûr~ïxŶ†¿° „¿¶í(Œm‘ì!$-ò6b»®®6l˜÷º¦Âÿ:XYZâ(Œm—7^v:å`ÛšÕŽ"Ûb;XûÄ‹OëÄ߯ØÖëð{y…±-’= >xî¹çÒ(¶›šš€ãŽ;îÓO?õ^\ͽâr`ÑÔ)ŽÂØvyãåy}û¯ÿÿrG‘…±ühÓþ—×¼1·xáœÙ‡öŽ]lë7Ú}øÑ»Û…±-’ „˜ I œØ¾½£0¶]Þxùʲ%Ààþý[öºËklo]»+üµç]?Ügl‹g–×]yƒ£0¶E2ž±Àå—_ž¦±=}útà¾ûîó^VýÓº£Ž:ÊQÛ.o¼¬_ù4ÐõôÓé-—רn¬?ðð¤É];wå/ÛGIJEÀ¿ 9ßQÛ"Ïøñã´iÛ/½ôpöÙg{¯G®vøÖ·€}/¿è(Œm—7FþâÍ×ãÛ¶mþ+.¯±½õÆó‡^@cûˆZ÷ÔK@¯ž½…±-’ñ„ŒBÒ¦ilòÉ'­Zµ~üã{¯k´öîÖXWSå(Œm—7^¶mÝhzç-Gal7óÝñwN‚ãFÞõÞËë6î]UYkl×¾ñ# ýw:8 c[$³  ´nÝúÓO?>¶£ý±í²²2ïuÖ Î=¨[0ßQÛ.o¼ì|ê)ÀÖ5«…±Ýœw?|m#$¸åú[ýiiàOŽâ( qÓ§al‹d0!`#ÿíèc{Μ9@nn®÷ºFë ÿõŸ@ÙÌŽÂØvyãåÀ¾}×W,wÆvsÞ--š ^yæMc;<¡Ã À¯npƶH())IëØ®¯¯N>ùdïõ/~W[êÕÝ»cû÷u‘›ÒUuyuð)'sÔQ“t‘›‘±=éžû“ß·ùŸ Ó–yÚ Ž=æØo›é("×¼IBÀ›7oNëØtéÒX»vm„Ó{]«®¸Ä!Û.o­¾âR‡Ð|í믺èßg€±&ݵØ!Û"™MHW k×®ÉÇ´ŽíÑ£G³gÏö^÷»XÕïbuyUSaÇöm7å=ºõŒ:¶¿ø]U¿]DBºcÆŒ‰AlWWW_|±÷ú!½«jl»¼ªÆö£÷Oƒ;7ì1¶õ0hl‹HHW ¦¦&±ÝÔÔ þð‡?4ÿ-ïuUcÛåU5¶Ë–C‚’ü¹Æ¶¦Zc[DB´B‚ƒÆ ¶C‡=ÔÏ x¯«Û.¯ª±ÝX WÏÞ@NÎñ««ê’ÿ¸»þÇÆ¶¦Bc[DB´Æ K>Æ ¶ #F4ÿïuUcÛåU5¶ƒ5e+ù }z÷>äüÞÆ¶¦Bc[DB´EEE±‰í;w999Ÿ|òIóßò^W5¶]^Uc;XûÄ‹OëÄßalkäÛ"r5D+ÐÐÐ›Ø 4xê©§¼×é]UcÛåU5¶ƒmÚÿòš7æ/œ3ûñÐÞÆ¶F®±-"!WÁƒ'cÛùùù@nn®÷º÷ºz¯»¼ªÆv0­ÞU5¶E$ä*PPP³ØÞ¾};Ю];ïuïõtSm—W]^c[ÕØ‘«ÀŽ;bÛóÎ;X¹r¥÷º÷zú¨Æ¶Ë«.¯±­jl‹HU`àÀÉǘÅö¬Y³€Ûo¿Ý{Ý{=}TcÛåU—רV5¶E$„*0{öìXÆöÖ­[o~ó›ÞëÞëé£Û.¯º¼Æ¶ª±-"!TmÛ¶Å2¶çœsP]]í½î½®‡ScÛåU—×ØÞºv×Û/|°ë‡ûþé]Uc[DB¢!W“±Œí’’àŠ+®ð^÷^×à±íòªËkl7ÖxxÒä®»~ÙßèV5¶E$$*r5Ʊý«_ý ìÞ½Û{Ý{]Sª±íòªËkloý°áü¡ä‹b[ÕØ‘§ äjŒc;0bÄ`úôéÞë)½×Um—W]^c{ü“ Á¸‘w½÷òº†{WUÖþý»ªÆ¶ˆ„8B¨&cÛµµµÀgœá½žº{]ÕØvyÕå5¶?|m#$¸åú[¿ì]Uc[DBœuuu±í@·nÝ€_|1ùè½®jl»¼ªÆväï–͇¯<󿾫jl‹È /¼tïÞ=ùûØž:u*——ù½Þr½×U[t¯»¼ªÆv‹MulOºç~ ýw:|Ù»ªÆ¶ˆ„,B¢fHl744G}ôo~ó›ðè½®jl»¼ª‘/¯±}ýU7ýû 0¶¿P5¶E$iÈR $j†Ävà’K.æÎ›#ö^Wø^wyU]Þ4øôÛnÊztëil¡jl‹HR Äiò1Cb»¼¼èׯ_*>¸÷ºª±íòªËkl?zÿ4H°sÃcû_Uc[Dú÷ïTTTÄ?¶¿èפ­ZµÊ{=rUm—W]^c»la9$(ÉŸklÿ“jl‹HHÑ/ùÕhñí¢¢¢}ÉÞ{]ÕØvyÕå5¶ëôêÙÈÉ9~uU]òw×ÿØØÖ ±-"!E¥Û¿ûÝïÚ´i¬]»Ö{½ÅªÛ.¯ª±ýeÖ”­ä/ôéÝwøóCxÛjl‹HˆP iÈÒ ŒíÀøñã‘#Gz¯G®ª±íòªËklkŸx±ãiø;Œm5¶EdÔ¨Q@ÒäcÆööíÛ!ÁücïuÕCÖØvyUíføÑ¦ý/¯ycnñÂ9³íml«±-’å„ü„!H36¶7Þx#0eÊïõ–©jl»¼ªÆvôïªÛ"™KÈO ¤hò1ccû•W^N8áïõøªßŸ=kÖ}÷>¿hAòñõËÃã’iS½×]Þ¿ªn®ËklëÓåkž4¹xfIòñ½WÖ‡ÇàŽõ»mcûp"ò)šá±6l0wî\ïu= îz®ö©’ÇV~¯$Â9ôÌ3»n¹9ù8yÜX G§ŽÞë.¯º¹1]^c[·¯o\6¯,Xÿþލ>æÄ»ÿèÚ¹kò±jÅ“`ý››âÿÿ5¶EbCO`èСÉÇ íªª* K—.Þëz\4u $ðd7¶]Þ/ÓÍuym}íÙ·!ÁªÊÚøÇvôÿ_c[$¾„ðB„fEl”––z¯«'»÷ºË«n®±ml§BcÛØ‘ÒÒÏÙ;« IŽ ûÕÌÌÌìe4,3–™™™™™ÆÃËÌ; fff>|½ïNºŠìÞš¼Ž÷\ŒŽ*•*;3ËÚøÿ‘R¹O‡~r]^Èvjj*s¾õÖ[ ¯ÿ™íŸ¯}zèÀ—GıÃïNˆíÝ_s³ßÛ»û§¬3!6-Ìïµ o¿ädý‘Ÿdÿ[QÁ×Ç2ŸµŠ²ÿžŸ« oߟ>ɲ^7ç5Ï5ÏM¸óÙ~·èãìÿþe¼ÈÕ›yïöÖ7ŽÒ³²:#y5ëí›Ïßþ¶àÄkž cù$ãšìkϵŠl¿Sð¡g8S(m²í?žOßúúÕ¬·Ê&Ù611râé)))åˆl#•+WfÚK–,1¼þ'´733êU«zñ…°æÈÕW\Üü1ë´<ýpÿއロ6}àçÅïNžxü¾ûx´tÌhn[שÃõËóæ&'5ªY“¥·ÔÿöäqÏÁì˜3›NxQäöoÜ0uŠƒ˜Ù¨ùÔƒmù÷âB58ºn-Ô|êI÷Ä>½µCÞÚ4}ªØ|sâz†'¸æ)úÜÛ¸f^ é¡:ÊÓ¯ŽñY+ÈøÖ©£¬Êc2N‘wmÙ¦ŸµuóýwÜÙ€¶m ¯›óšçšç&ÊylÚ(ß9Ôÿ}豤 ©jP£j­ûïy Þs "ßmP§Ú4ëñ#'sÝ·û€×sÞ}¡UÛ믽ž®.¼ð"^ß—zØs؇v¯\¡ªŽ„×á®ï~ä0ÆÚ5žá‘Ø\yÅU]Úww(bãúMÌêÅëe{®v]1ƲY£– Ol˜‘NÎöGvDÿRëv\/œ¹Fz÷÷ð´[ÇžkåO¶S6g0 X˦­Ó¶î Ìž2ŸatjÛµðäkL3¹bþß(ú|½ÇÓ§[> £¢\ëfÏ«eû:²øe‡l›˜˜,^¼÷„xr]¾ÈvZZ3¿å–[ ¯—vK]0ÿ¼0úö®L‰‰ÑÜxí5t¦N¯gmÝ­ÀJ€rdo àŸ³KdI£fî°¡j3²k—¨6ebMb“¶p(Ô¨i¹eæ l>;|0òúÃkVËuÏ6­Ud÷Y+OÈŽ±¬•#~˜˜›ÓOÛF å©‘ms^ó\óÜ:¯‘mxl­jµÏ‹&+±éðb'Ñœ9”|÷ôÁ\Ñ1‰Ûî{ ÉTFäÌGwŸ*q0Ëæ­Š:’ºÏÔ'4-6k—nrž*å>u G»’,¼Ý‘‡x˜¸46‘ãÜ•´}Å'+q ÛT=dÛs­<Éöð£¢ÿó2uÓÏSW€sB¶=¿Qôùz>&²Qò2B¶MLL ›8&ijܑm¤jÕªL~Ñ¢E†×K¯#Ò(Ö±õkËË!ÇrÉèQh| F'2&šìm[ƒ¯?[¹RŒa(¯MšŸ´ƒhR(‡´}+–ëïžØ¸žôѼ¤íA,{põJ¹å§_MK%üõzFZÖ­DIˆÉìã¢|§MÕx6ÿ(.$Ø%xáúÝ;²+‡!¬š0žX™ÏZù@v~Wƒ{+Æ…9ðÓ³Ò@™ÙEšÔ®5ø°3[6^7ç5Ï5ÏMˆóÙÜw˜|ÖÞÝúå+þèµ/çBðDI´Sβ’[b×ÁwG +zˆ–’m˜ê±=§ AÃBEÓ¶Mû𑓬´yýòÍ$oç-"-ÊuË6aóZö;PMݲ“ôÈ$Ÿ6~¡ÖÊÉ…l‹Œ:.ëpþô£DnE³tÞJlèÓÊm¢ç3Z¦¯d[yþ¤ÑS!¥>kåI¶·¬Þ!èëþ´#dËó.rQJœ\ûÑ?Œ4zí’Q—ÎóE¯ÿx„l‹LŸ0›%Ÿs»n¢!—ÁÈvYh&. åäº<’파 æóÍ7^/½6¸C{ywÏ® žÜNÑËÉ:à]¹¿ªÍG‹rÎÐ!dõ÷+Š’ÜË‘dAç…«p,¯'ÏŸ‹ q6®ù!sðÝVuž3vi!{í €õj9¼s'Ñë–ÔÈŸ ^‘½ðÿµòìœå+ö»—- ö³hÔÙ~ !ڳ†×ÍyÍsÍsâ¼F¶!`òYIœvöZKŽ'žå¦6JhŸ©õœÜ*Ù†%ÍxK» iDåux£*ßÎÿ@”$ŠsÛ£sï¨ñÛiãgŠ2ém¸np÷µ²å=ÌJ¶…¸ú¯•Ùþä/% ýñGŸ$)=Ø$Þó÷‡l7ª×$|#½ÿ7ræë9‡lO;=ø»d§‹ž(º‘í„‹‰ÉM7Ý„?¦§§—S²­gn/X°Àðz)5ð1+ÌÎLGTELêÛG4`_'uù¸±bóù‘C¢ÑdT§7Ð*úNÍšê¦G§¡üèÀ>ém\Ï‘ª$d’ª6+Çslôòˆ/]om¥¢'vW"d[ǶVáH—Dí"c•ÒÏÔþý´y‘M­†×ÍyÍsÍsè¼F¶ ðʇ>¾÷Œór+„æ 8Zn‰ŽŠiá¢Y³dƒC¶ß+þ$Ø»Ž%-·¾ú9µ¾‚MÂÑBí;#™5yqrâº\;ôOcX«p²M€]n·­KvúéÑ©Wd?Hþ‰WJiNCéùœùúGÉ6™NÑ;6äkö‘íÄŠ‰ SÏÖ.¿d;33“U¸ì²Ë~ùå—?¯ÇÞþð: –,/²vòÄȧR襆 å–êDbL~iPRNIn²³aRnœU`·†Ú!„¥q0Puä`´x’Øè6Kmä‘Ê£Õ'!;ù¢A3²Rµ‡ÈîÄÁü×ʲË6Zþ;ª[W§ÉOtkÙ2ØO‡¦M ¯—ç5Ï5Ï5²s+m²=lÀH¥ÁN›?c1è·ä ;QM¡‚P/Èsl_•['“Y~E sPÒ·í†ÎÉ5Ìü\£%çYlæM_ù”þyÔ¢I« Ùf'sd!1Ér/‘lSQ,¶µ 'Û+®Õ¼ëþ=›†ŽÉQ×~œ_„H£t„âížß(r¾þãáVÿâf³ £¦$l›˜˜@-!˜8#d³\“m¤I“&,ÄàÁƒ ¯Ç½)ÌeËeäS¶ ÊK¹åœž`üêãƒûå6eÁ<²éÞ-²°oOTÈNå^¹~%5Åy=²ª“S±IbnòhÚ€þAÈÎöј!;¯Ö*²3ÓóÂEBpn?†×ÍyÍsÍsé¼F¶©)­‰ÇNÛ±>ÅIê ª\ R­•ÔlK6òÿJ¶©zMZ¸\Ϙ8ÇŒ[ëËÁJc`²ë8H¶ô3Ù&^ÛZ…“푃ǔèw'öe9ýhË9Rl{}#w¾þãÑ¥ƒ“Ÿë/{I Ù611Zâ‰ÐL®Ë;Ù.**:»îõ×-‹5¾í“ƒdmÉót)²ä U¶oÒXk-9‚kÊ8r ;˜>²ƒ­ µ9WŠ0É/‚ª#‡êì™”íÁFý'y´iú´ dççâÙý×*²3S=¯ˆ²OQƒ4²mÎkžkž[¦œ×RÐ9´é\5®Ù®¬9ÉNü–šdš{L‰,‡lÃôÂÉ6åÄÏ^lTä"vªÅÌÎ5Z²©Å†"Ïåv6T ÙÔgh¼È¶ÿZ…“mÂÎr˲,šµ,j#VÙæ;«G#ßï¹óõ.ð§‘U.=ðë‰"Û&&&JñDh¦‘íK¿~ýXŽ–-[^o£:‘Öv¥¼ 7IÓzÂÅ©ÉR•w`»¶òȲŸ«q‘Æ$Ù˜ì–$I\îÂz·Ö‘<Š7d÷_+dT*E9{hµ$×—- F¶ÍyÍsÍsË”óÙV–(iÆÎáÌNÔTk•Q‰º_Ê<ýÉvøYßÒ9gk¹ƒ1‰’àDM…Ô)!wNçVÆXJdÛ­Âɶ–þ†Ä:ý¼‘û ™¹DZóißȯÿxté8‡Ì1Ë>\ =dlß“(²mbb©Ä !˜gïlÿðÃ^x!‹²gÏÃëñm o y9…|–=›+ÅA>Á@lq$[RwÆ ²kécŒƒzß{–/¥±\wnÞÌy½u:¯û1ëtÜ!»ÿZù@v¯Ì'ØOîŽm¢Oš;Çȶ9¯y®yn™r^#ÛJ´ˆŽ:b9a«j¥êA=;¢…NK*8AÑx‘mÍGØ›YꨅÍÉŽÖÒeÒH>×íߥD¶ý×*œl+5¥Æ¸3¶çjוc#Ûßȯÿxté"KÁëénŧßHÙ611Nâƒ\pÁ÷ßodû¿2{ölÖ¥B… †×ãÛH­Tü×Â|QÄåXZ £cÏ®NôšN‰&^ÆéDÁRI4N²•>|‘slh”>%àX4þ]“` ““B »çZù@vÎæ•~Ô¨þÙSª”™Òc6²mÎkžkž[¦œ×È6”•@¥ÔÐÚ|@³‚)Ö휛%ÍÒ¢WöG²½eM’t˯Kˆ˜c´…:êvhȵšgVi=m¡»dÑø“mM_çð°²í¹Vžçl“‰-š +¶hçc†ŽwÊŒù“mïoäÎ×s<Ùf´[ÎëF£Kš²mbbÄ ¡–ª1²}VîûO ߊ+ ¯Ç±‘Y§JVÀ"Ø ®·$:ö¯¥§òH„Óe£Cö±w¸yÅ@î-rŠˆËÌâÞ Ì”Deffffffff®°x~ÒT+?hå¼p²«ä³ý´’ç_{¦è–ð—ø~1qJKõÙBFRÙ!ËÔt;7o&]IøÒBY·ìÏPŠ:ÍnÙã×*rË®«ˆ2“ÍÔhœl»óºçºçÖ4çuÙ°ë÷êqK)@%àš«°†º2)¶ù#¸ªÆE´¦‘E¹T9g®Dr­°¾Ø~´¬`[„mÖ¸= ¶ã×*l¶ŠŒ³MËv¶ªtÍ"ÛÏ(;ßøñhéd˜ØôpÑå®°íææÄ •9y¶·lÙÂê”””üþýÛ÷ëø÷ëúÕáÝ»5L±/X|sËëâ"öñÔ‰T–¶°£úõM¥³ÓÂáHj—¶mѰ#OI Ñ/;õÔ€9Œ 법Ù=oŽÒ¿_½Ö½°~­ÒÃÙ…=J¦ÈÈœŠ­zÅáµØ1ú Q„e ƒR`M¦{æÏýO;¾_wçuÏuÏ­^çun´ 5Ét/Úh·rÏ [ÔþútïŸ ¶‰‘F‚mªC Oùèð`9"a63 7\åaSá´–êBXÝX¾Œ!L¶oË!RPçæ3¿[+‰„Ùeéíëö¨F¢ÙÙv"þ¢žQv¾ñã1‚4ލŒýî Ð^õ`ÛÍÍ  Ä7oÞì`;ß:uêTá×Ùl[ÜéÄŠåKFÜ¿pâ@bª®?6îˆ÷2’û{véØg6¬‡êïÞùó–ŽuzõʯgÏ”³Ç÷'ßÙ¹ƒ=zU®±;È¥PEÚ8m áµøv|¿îÎëžëž[õÎë`Û¡§œ_4k,YàIA¬êúƒŒ1¬Z´'ììßÝK·¯Û=mü,®R_=}[X·ð¼bL_íTåZÁ^ž9q³Pd¸jþÂùÆG`Vv>?½õÁ3ÎóŒtÞÁ¶›[5RnwìØñŸ%lß¹óWÊâÄöîÂêôßãø@dб´°JŽU¡µJk ›ÍÐ× `*(@;¬0³Ô„h $ Ð,»ÚÐÄì°Õ.Aûܯßð·¬Û­¶™Î̼^>À®‡ïÛ©sffÜëfîu×Öx¯Ø6ûçÞÛožØ†µQñ˜N夨~“o¿ý6I¯×s¯›¹×=^3Wl¿y&¶^¯—äòåË+Ûo²ÿþ$cccîu3÷ºÇk&¶Åöÿ5ÛÀØØX’ýû÷··!¶ïÞ½›Îüü¼{Ý̽îñZÿÌãÛf+ß-÷ßÿõ?b>ºùùùtîÞ½+¶ßÖÈÈH’¡¡!÷º™{Ýã5ëÿÇ+¶ÍÄ6¬½¡¡¡$###íí‰í/^ &™œœt¯›¹×=^3±-¶íïÛÀääd’ÁÁÁçÏŸ‹íw355•dÛ¶m‹‹‹îõ•™¹×=^3±-¶Ml‹‹‹Û¶mKrãÆú£Ø~gÃÃÃINœ8á^_™™{Ýã5ÛbÛÄ6pâĉ$ÃÃÃíýˆí¥¥¥$îu3÷ºÇk&¶Å¶‰m`bb"ÉŽ;–––Äöû»uëV:>t¯›¹×7óã5ÛbÛÄ6077—N¥bû7Äv9wî\’C‡¹×7ó̽îñš‰m±mb¨0LR‘Øþ=±ýúõë½{÷&¹xñb_Üëï?÷º¹×ߟÇk&¶ßbÛ6Dl—.]JRyX‘(¶?Œû÷ï§3==í^7s¯o¶Çk&¶Å¶‰m b0ÊÃVÄö‡råÊ•$»wï^ùµõȽnîõµçñšÇ‹Ø¶ Û@e`Å`’ ÃVÄö‡uìØ±$§OŸv¯›¹×7Ïã5óxŶ‰m 20I%a[ bûÑ£G[·nM2>>î^7s¯{¼æñ"¶m3Ä6P˜¤b°’Pl¯–Û·o¯Â?Þv¯›{×<Þ~$¶MlwîÜI§b°­±]._¾œd``àéÓ§îu3÷ºÇk/bÛ6jl}•~I*ÛjÛåäÉ“IŽ=ê^7s¯{¼æñ"¶m£Æ6päÈ‘$€mmˆíååå={ö$u¯›¹×=^óxÛ¶ñb¨ÜKòé§ŸVŠíµ3;;›Îµk×Üëfîu×<^Ķm¤Ø*ôÒ©ôkkIl—ÉÉÉUù¯ï^7÷:¯y¼bÛLlC|¶úý÷ß·µ'¶ËÙ³g“ìÚµkaaÁ½næ^÷xÍã]ï͉m â®/Iå^ûXÄv9~üx’ƒ¾zõʽnæ^÷xÍãEl›Ø†õ«²®â.I…^û¸ÄöË—/{½Þ?¾¡Î½næ^÷xÍãEl›Ø†uùËS•xüñ‡Øþø?~¼sçÎ$çÏŸw¯›¹×=^óxÛ&¶a=ª KRqW‰×ŠØî÷îÝKç»ï¾s¯›¹×=^óxÛ&¶a}©”K§â®±Ý?nÞ¼™Îõë×Ýëfîu×<^͉mX/*âÒ™ššjEl÷›«W¯¦333ã^7s¯{¼æñ"¶MlCÿ«|K§‚®±ÝŸ.\¸dË–-³³³îu3÷ºÇk/bÛÄ6ô³ ·Ê·$£££­ˆí~væÌ™$Û·oÿñÇÝëfîu×<Þþ$¶Ml•lnI*âZÛýïÔ©SI>ù䓟þ¹ßîu³~[cã?^óxŶYßÍÛ„ŠµJ¶$•o­ˆíõâ믿N²gÏž……÷º™{Ýã5Wl›‰mèOž<©XKRáÖÖ±ý×_}õÕWIöíÛ·´´Ôèh•iI*Ù*ÜÄöúóçŸ~ñÅI<¸¼¼Ü>**Í8äðáÕl­ˆíõèÙ³gŸþy’/¿üRo|ÜÒ®4KR™öûï¿·"¶×¯ß~ûí³Ï>KràÀò÷ɨ[ùL»í×_mEl¯wõ?råóí}ûö=yò¤°†*ÄöîÝ»ò™v} ÚŠØÞê¯(>|xåûÉúé§¶&¨[ùîñúR­gÏžµ"¶7Ø÷¥­|?yý˜ÛÜÜ\[eT|­üžv娯üF4±½ò{`+¿¿½}ûö´U@eWÅ×Êïi¯üÊ—ØÞÈN:•dË–-?üðC[TpUv%©k›Ø.gΜIçúõë탠R+НVÄöæ1::šÎøøxû@¨ÈJçÂ… ­ˆíÍæêÕ«éœ?¾ýkT^¥SÁÕŠØÞœ¦¦¦Òùæ›o^½zÕÞ •T'OžLçæÍ›­ˆíÍìÞ½{;wîLrðàÁ………öލ˜ª¤JRyU‘ÕŠØæ—_~éõzIvíÚ5;;ÛÞ•QSI*¬?~ÜøOlóòåËãǧsíÚµö¨€J§’ªÂªñÏØæìٳ錎Ž6Þîgž*¦oˆm&''Ó9räÈÓ§OÛ?P¹tôèÑt*£ÿolóàÁƒ={ö$¸sçNû¦§§+—’T:ùÞ«wˆm–——ÿóõããã €N%R:M•Nwm._¾œÎéÓ§Ÿ?Þ6±Ê¢Š£t*—ïÛܾ}{ëÖ­IvïÞ===Ý6¥ ¢Ê¢$•HJÛ22’N¯×›™™ië ÀÌÌL¯×KgddäÅ‹ÿËÎSA „]k!å6HHDP¢ 1@… Ì €{o‹Ó@1ßÅ4SÛp÷µÖ™Õdæ½Ör÷ê†ØÆóçìœSJÝïw2 ”>ŸOkm¡”ÒZ;à?´ÖJ)!kíãñ ”’Áív“R:çrÎ8Blÿcߎ` †¡0Ž—6çM6¯TëXOšl´9?§º6«ã6w(¬©»7y´;oržÛ÷ãGÏ>øÃ+¤”ö}_×UJ)*ã8cˆ(„cdf| €™cŒ!"2Æ Ã *RÊeY¶m»ïûŒí—Cã}ž§snžg¥TÛ¶¢ÒuÖÚZKDÞûï}ι”òü€RJÎùº.ï=YkµÖ}ß‹JÓ4J©išœsÇqüj°?ìÝÅ ÇñÝæœ[—kŽÛÝæknŽ9m—kE º,Š¢à=‡Ñ»g¿ûÝ—¾€Ø ¢çyŒ1ÇqpÎçyž^0Æ„RÊu]•RZëó<­µÎ9ï}!ÆHD)¥RJ­µµÖ{c|þ `ŒÑ{o­ÕZK))%"Š1†¼÷Î9kíu]Zk¥Ô¶mRJ!clz±, ç|ßwcÌ}ßXaï± sþ²oGEC1Àþê'8ÁIë'8ÛÍÆ;â#Ilï®$’þ‘òœªªªªª™@RÒÝÙN¾öëXvà‡R©tG¥R©Œk\ã׸Æ5Ž=ÇøÔâ÷ÝçíºÏìý<Ï÷o Û0çcÜ÷Ý{o­ÕZK)9ç”RŒ1„p]×yžÇqìûþ~¿·m[×uY–ðc˲¬ëºmÛëõÚ÷ý8Žó<¯ë !ÄSJ9çRJ­µµÖ{ÿ|>cŒ9çdddmmmà·Ùddddmmm@¶@¶@¶ÙÙÙþÅtÞ!IEND®B`‚ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/index.rst000066400000000000000000000022341504532661100236460ustar00rootroot00000000000000.. Copyright (c) 2016, Stephen Finucane Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========= Tutorials ========= Getting started with Open vSwitch (OVS) and Open Virtual Network (OVN) for Open vSwitch. .. toctree:: :maxdepth: 2 ovn-sandbox ovn-openstack ovn-rbac ovn-ovsdb-relay ovn-ipsec ovn-interconnection ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-interconnection.rst000066400000000000000000000172041504532661100265430ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =================== OVN Interconnection =================== This document provides a guide for interconnecting multiple OVN deployements with OVN managed tunneling. More details about the OVN Interconnectiong design can be found in ``ovn-architecture``\(7) manpage. This document assumes two or more OVN deployments are setup and runs normally, possibly at different data-centers, and the gateway chassises of each OVN are with IP addresses that are reachable between each other. Setup Interconnection Databases ------------------------------- To interconnect different OVNs, you need to create global OVSDB databases that store interconnection data. The databases can be setup on any nodes that are accessible from all the central nodes of each OVN deployment. It is recommended that the global databases are setup with HA, with nodes in different avaialbility zones, to avoid single point of failure. 1. Install OVN packages on each global database node. 2. Start OVN IC-NB and IC-SB databases. On each global database node :: $ ovn-ctl [options] start_ic_ovsdb Options depends on the HA mode you use. To start standalone mode with TCP connections, use :: $ ovn-ctl --db-ic-nb-create-insecure-remote=yes \ --db-ic-sb-create-insecure-remote=yes start_ic_ovsdb This command starts IC database servers that accept both unix socket and TCP connections. For other modes, see more details with :: $ ovn-ctl --help Register OVN to Interconnection Databases ----------------------------------------- For each OVN deployment, set an availability zone name :: $ ovn-nbctl set NB_Global . name= The name should be unique across all OVN deployments, e.g. ovn-east, ovn-west, etc. For each OVN deployment, start the ``ovn-ic`` daemon on central nodes :: $ ovn-ctl --ovn-ic-nb-db= --ovn-ic-sb-db= \ --ovn-northd-nb-db= --ovn-northd-sb-db= [more options] start_ic An example of ```` is ``tcp::6645``, or for clustered DB: ``tcp::6645,tcp::6645,tcp::6645``. ```` is similar, but usually with a different port number, typically, 6646. For ```` and ````, use same connection methods as for starting ``northd``. Verify each OVN registration from global IC-SB database, using ``ovn-ic-sbctl``, either on a global DB node or other nodes but with property DB connection method specified in options :: $ ovn-ic-sbctl show Configure Gateways ------------------ For each OVN deployment, specify some chassises as interconnection gateways. The number of gateways you need depends on the scale and bandwidth you need for the traffic between the OVN deployments. For a node to work as an interconnection gateway, it must firstly be installed and configured as a regular OVN chassis, with OVS and ``ovn-controller`` running. To make a chassis as an interconnection gateway, simply run the command on the chassis :: $ ovs-vsctl set open_vswitch . external_ids:ovn-is-interconn=true After configuring gateways, verify from the global IC-SB database :: $ ovn-ic-sbctl show Create Transit Logical Switches ------------------------------- Transit Logical Switches, or Transit Switches, are virtual switches for connecting logical routers in different OVN setups. :: $ ovn-ic-nbctl ts-add After creating a transit switch, it can be seen from each OVN deployment's Northbound database, which can be seen using :: $ ovn-nbctl find logical_switch other_config:interconn-ts= You will also see it with simply ``ovn-nbctl ls-list``. If there are multiple tenants that require traffic being isolated from each other, then multiple transit switches can be created accordingly. Connect Logical Routers to Transit Switches ------------------------------------------- Connect logical routers from each OVN deployment to the desired transit switches just as if they are regular logical switches, which includes below steps (from each OVN, for each logical router you want to connect). Assume a transit switch named ``ts1`` is already created in ``IC-NB`` and a logical router ``lr1`` created in current OVN deployment. 1. Create a logical router port. :: $ ovn-nbctl lrp-add lr1 lrp-lr1-ts1 aa:aa:aa:aa:aa:01 169.254.100.1/24 (The mac and IP are examples.) 2. Create a logical switch port on the transit switch and peer with the logical router port. :: $ ovn-nbctl lsp-add ts1 lsp-ts1-lr1 -- \ lsp-set-addresses lsp-ts1-lr1 router -- \ lsp-set-type lsp-ts1-lr1 router -- \ lsp-set-options lsp-ts1-lr1 router-port=lrp-lr1-ts1 3. Assign gateway(s) for the logical router port. :: $ ovn-nbctl lrp-set-gateway-chassis lrp-lr1-ts1 [priority] Optionally, you can assign more gateways and specify priorities, to achieve HA, just as usual for a distributed gateway port. Similarly in another OVN deployment, you can connect a logical router (e.g. lr2) to the same transit switch the same way, with a different IP (e.g. 169.254.100.2) on the same subnet. The ports connected to transit switches will be automatically populated to ``IC-SB`` database, which can be verified by :: $ ovn-ic-sbctl show Create Static Routes -------------------- Now that you have all the physical and logical topologies ready, simply create static routes between the OVN deployments so that packets can be forwarded by the logical routers through transit switches to the remote OVN. For example, in ovn-east, there are workloads using 10.0.1.0/24 under lr1, and in ovn-west, there are workloads using 10.0.2.0/24 under lr2. In ovn-east, add below route :: $ ovn-nbctl lr-route-add lr1 10.0.2.0/24 169.254.100.2 In ovn-west, add below route :: $ ovn-nbctl lr-route-add lr2 10.0.1.0/24 169.254.100.1 Now the traffic should be able to go through between the workloads through tunnels crossing gateway nodes of ovn-east and ovn-west. Route Advertisement ------------------- Alternatively, you can avoid the above manual static route configuration by enabling route advertisement and learning on each OVN deployment :: $ ovn-nbctl set NB_Global . options:ic-route-adv=true \ options:ic-route-learn=true With this setting, the above routes will be automatically learned and configured in Northbound DB in each deployment. For example, in ovn-east, you will see the route :: $ ovn-nbctl lr-route-list lr1 IPv4 Routes 10.0.2.0/24 169.254.100.2 dst-ip (learned) In ovn-west you will see :: $ ovn-nbctl lr-route-list lr2 IPv4 Routes 10.0.1.0/24 169.254.100.1 dst-ip (learned) Static routes configured in the routers can be advertised and learned as well. For more details of router advertisement and its configure options, please see ovn-nb(5). ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-ipsec.rst000066400000000000000000000155661504532661100244560ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ================== OVN IPsec Tutorial ================== This document provides a step-by-step guide for encrypting tunnel traffic with IPsec in Open Virtual Network (OVN). OVN tunnel traffic is transported by physical routers and switches. These physical devices could be untrusted (devices in public network) or might be compromised. Enabling IPsec encryption for the tunnel traffic can prevent the traffic data from being monitored and manipulated. More details about the OVN IPsec design can be found in ``ovn-architecture``\(7) manpage. This document assumes OVN is installed in your system and runs normally. Also, you need to install OVS IPsec packages in each chassis (refer to Open vSwitch documentation on ipsec). Generating Certificates and Keys -------------------------------- OVN chassis uses CA-signed certificate to authenticate peer chassis for building IPsec tunnel. If you have enabled Role-Based Access Control (RBAC) in OVN, you can use the RBAC SSL/TLS certificates and keys to set up OVN IPsec. Or you can generate separate certificates and keys with ``ovs-pki`` (refer to :ref:`gen-certs-keys`). .. note:: OVN IPsec requires x.509 version 3 certificate with the subjectAltName DNS field setting the same string as the common name (CN) field. CN should be set as the chassis name. ``ovs-pki`` in Open vSwitch 2.10.90 and later generates such certificates. Please generate compatible certificates if you use another PKI tool, or an older version of ``ovs-pki``, to manage certificates. Configuring OVN IPsec --------------------- You need to install the CA certificate, chassis certificate and private key in each chassis. Use the following command:: $ ovs-vsctl set Open_vSwitch . \ other_config:certificate=/path/to/chassis-cert.pem \ other_config:private_key=/path/to/chassis-privkey.pem \ other_config:ca_cert=/path/to/cacert.pem Enabling OVN IPsec ------------------ To enable OVN IPsec, set ``ipsec`` column in ``NB_Global`` table of the northbound database to true:: $ ovn-nbctl set nb_global . ipsec=true With OVN IPsec enabled, all tunnel traffic in OVN will be encrypted with IPsec. To disable it, set ``ipsec`` column in ``NB_Global`` table of the northbound database to false:: $ ovn-nbctl set nb_global . ipsec=false .. note:: On Fedora, RHEL and CentOS, you may need to install firewall rules to allow ESP and IKE traffic:: # systemctl start firewalld # firewall-cmd --add-service ipsec Or to make permanent:: # systemctl enable firewalld # firewall-cmd --permanent --add-service ipsec Enforcing IPsec NAT-T UDP encapsulation --------------------------------------- In specific situations, it may be required to enforce NAT-T (RFC3948) UDP encapsulation unconditionally and to bypass the normal NAT detection mechanism. For example, this may be required in environments where firewalls drop ESP traffic, but where NAT-T detection (RFC3947) fails because packets otherwise are not subject to NAT. In such scenarios, UDP encapsulation can be enforced with the following. For libreswan backends:: $ ovn-nbctl set nb_global . options:ipsec_encapsulation=true For strongswan backends:: $ ovn-nbctl set nb_global . options:ipsec_forceencaps=true .. note:: Support for this feature is only availably when OVN is used together with OVS releases that accept IPsec custom tunnel options. Troubleshooting --------------- The ``ovs-monitor-ipsec`` daemon in each chassis manages and monitors the IPsec tunnel state. Use the following ``ovs-appctl`` command to view ``ovs-monitor-ipsec`` internal representation of tunnel configuration:: $ ovs-appctl -t ovs-monitor-ipsec tunnels/show If there is a misconfiguration, then ``ovs-appctl`` should indicate why. For example:: Interface name: ovn-host_2-0 v1 (CONFIGURED) <--- Should be set to CONFIGURED. Otherwise, error message will be provided Tunnel Type: geneve Remote IP: 2.2.2.2 SKB mark: None Local cert: /path/to/chassis-cert.pem Local name: host_1 Local key: /path/to/chassis-privkey.pem Remote cert: None Remote name: host_2 CA cert: /path/to/cacert.pem PSK: None Custom Options: {'encapsulation': 'yes'} <---- Whether NAT-T is enforced Ofport: 2 <--- Whether ovs-vswitchd has assigned Ofport number to this Tunnel Port CFM state: Disabled <--- Whether CFM declared this tunnel healthy Kernel policies installed: ... <--- IPsec policies for this OVS tunnel in Linux Kernel installed by strongSwan Kernel security associations installed: ... <--- IPsec security associations for this OVS tunnel in Linux Kernel installed by strongswan IPsec connections that are active: ... <--- IPsec "connections" for this OVS tunnel If you don't see any active connections, try to run the following command to refresh the ``ovs-monitor-ipsec`` daemon:: $ ovs-appctl -t ovs-monitor-ipsec refresh You can also check the logs of the ``ovs-monitor-ipsec`` daemon and the IKE daemon to locate issues. ``ovs-monitor-ipsec`` outputs log messages to ``/var/log/openvswitch/ovs-monitor-ipsec.log``. Bug Reporting ------------- If you think you may have found a bug with security implications, like 1. IPsec protected tunnel accepted packets that came unencrypted; OR 2. IPsec protected tunnel allowed packets to leave unencrypted; Then report such bugs according to :doc:`/internals/security`. If bug does not have security implications, then report it according to instructions in :doc:`/internals/bugs`. If you have suggestions to improve this tutorial, please send a email to ovs-discuss@openvswitch.org. ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-openstack.rst000066400000000000000000002446451504532661100253440ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ====================== OVN OpenStack Tutorial ====================== This tutorial demonstrates how OVN works in an OpenStack "DevStack" environment. It was tested with the "master" branches of DevStack and Open vSwitch near the beginning of May 2017. Anyone using an earlier version is likely to encounter some differences. In particular, we noticed some shortcomings in OVN utilities while writing the tutorial and pushed out some improvements, so it's best to use recent Open vSwitch at least from that point of view. The goal of this tutorial is to demonstrate OVN in an end-to-end way, that is, to show how it works from the cloud management system at the top (in this case, OpenStack and specifically its Neutron networking subsystem), through the OVN northbound and southbound databases, to the bottom at the OVN local controller and Open vSwitch data plane. We hope that this demonstration makes it easier for users and potential users to understand how OVN works and how to debug and troubleshoot it. In addition to new material, this tutorial incorporates content from ``ovn_devstack.rst`` in OpenStack neutron, by Russell Bryant and others. Without that example, this tutorial could not have been written. We provide enough details in the tutorial that you should be able to fully follow along, by creating a DevStack VM and cloning DevStack and so on. If you want to do this, start out from `Setting Up DevStack`_ below. Setting Up DevStack ------------------- This section explains how to install DevStack, a kind of OpenStack packaging for developers, in a way that allows you to follow along with the tutorial in full. Unless you have a spare computer laying about, it's easiest to install DevStack in a virtual machine. This tutorial was built using a VM implemented by KVM and managed by virt-manager. I recommend configuring the VM configured for the x86-64 architecture, 6 GB RAM, 2 VCPUs, and a 20 GB virtual disk. .. note:: Since we will be creating VMs inside this VM, it is important to have nesting configured properly. See https://github.com/openstack/devstack/blob/master/doc/source/guides/devstack-with-nested-kvm.rst for details on that. Also, if you happen to run your Linux-based host with 32-bit userspace, then you will have some special issues, even if you use a 64-bit kernel: * You may find that you can get 32-bit DevStack VMs to work to some extent, but I personally got tired of finding workarounds. I recommend running your VMs in 64-bit mode. To get this to work, I had to go to the CPUs tab for the VM configuration in virt-manager and change the CPU model from the one originally listed to "Hypervisor Default' (it is curious that this is not the default!). * On a host with 32-bit userspace, KVM supports VMs with at most 2047 MB RAM. This is adequate, barely, to start DevStack, but it is not enough to run multiple (nested) VMs. To prevent out-of-memory failures, set up extra swap space in the guest. For example, to add 2 GB swap:: $ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 $ sudo mkswap /swapfile $ sudo swapon /swapfile and then add a line like this to ``/etc/fstab`` to add the new swap automatically upon reboot:: /swapfile swap swap defaults 0 0 Here are step-by-step instructions to get started: 1. Install a VM. I tested these instructions with Centos 7.6. Download the "minimal install" ISO and booted it. The install is straightforward. Be sure to enable networking, and set a host name, such as "ovn-devstack-1". Add a regular (non-root) user, and check the box "Make this user administrator". Also, set your time zone. 2. You can SSH into the DevStack VM, instead of running from a console. I recommend it because it's easier to cut and paste commands into a terminal than a VM console. You might also consider using a very wide terminal, perhaps 160 columns, to keep tables from wrapping. To improve convenience further, you can make it easier to log in with the following steps, which are optional: a. On your host, edit your ``~/.ssh/config``, adding lines like the following:: Host ovn-devstack-1 Hostname VMIP User VMUSER where VMIP is the VM's IP address and VMUSER is your username inside the VM. (You can omit the ``User`` line if your username is the same in the host and the VM.) After you do this, you can SSH to the VM by name, e.g. ``ssh ovn-devstack-1``, and if command-line completion is set up in your host shell, you can shorten that to something like ``ssh ovn`` followed by hitting the Tab key. b. If you have SSH public key authentication set up, with an SSH agent, run on your host:: $ ssh-copy-id ovn-devstack-1 and type your password once. Afterward, you can log in without typing your password again. (If you don't already use SSH public key authentication and an agent, consider looking into it--it will save you time in the long run.) c. Optionally, inside the VM, append the following to your ``~/.bash_profile``:: . $HOME/devstack/openrc admin It will save you running it by hand each time you log in. But it also prints garbage to the console, which can screw up services like ``ssh-copy-id``, so be careful. 2. Boot into the installed system and log in as the regular user, then install Git:: $ sudo yum install git .. note:: Support for `Centos 7 in Devstack `_ is going away, but you can still use it. Especially while Centos 8 support is not finished. The one important caveat for making Centos 7 work with Devstack is that you will explicitly have to install these packages as well:: $ sudo yum install python3 python3-devel If you installed a 32-bit i386 guest (against the advice above), install a non-PAE kernel and reboot into it at this point:: $ sudo yum install kernel-core kernel-devel $ sudo reboot Be sure to select the non-PAE kernel from the list at boot. Without this step, DevStack will fail to install properly later. 3. Get copies of DevStack and Neutron and set them up:: $ git clone https://git.openstack.org/openstack-dev/devstack.git $ git clone https://git.openstack.org/openstack/neutron.git $ cd devstack $ cp ../neutron/devstack/ovn-local.conf.sample local.conf .. note:: Depending on the name of the network device used by the VM, devstack may be unable to automatically obtain its IP address. If that happens, edit ``local.conf`` and explicitly provide it (X marks the spot):: HOST_IP=X If you installed a 32-bit i386 guest (against the advice above), at this point edit ``local.conf`` to add the following line:: CIRROS_ARCH=i386 4. Initialize DevStack:: $ ./stack.sh This will spew many screenfuls of text, and the first time you run it, it will download lots of software from the Internet. The output should eventually end with something like this:: This is your host IP address: 172.16.189.6 This is your host IPv6 address: ::1 Horizon is now available at http://172.16.189.6/dashboard Keystone is serving at http://172.16.189.6/identity/ The default users are: admin and demo The password: password 2017-03-09 15:10:54.117 | stack.sh completed in 2110 seconds. If there's some kind of failure, you can restart by running ``./stack.sh`` again. It won't restart exactly where it left off, but steps up to the one where it failed will skip the download steps. (Sometimes blindly restarting after a failure will allow it to succeed.) If you reboot your VM, you need to rerun this command. (If you run into trouble with ``stack.sh`` after rebooting your VM, try running ``./unstack.sh``.) At this point you can navigate a web browser on your host to the Horizon dashboard URL. Many OpenStack operations can be initiated from this UI. Feel free to explore, but this tutorial focuses on the alternative command-line interfaces because they are easier to explain and to cut and paste. 5. The firewall in the VM by default allows SSH access but not HTTP. You will probably want HTTP access to use the OpenStack web interface. The following command enables that. (It also enables every other kind of network access, so if you're concerned about security then you might want to find a more targeted approach.) :: $ sudo iptables -F (You need to re-run this if you reboot the VM.) 6. To use OpenStack command line utilities in the tutorial, run:: $ . ~/devstack/openrc admin This needs to be re-run each time you log in (but see the following section). DevStack preliminaries ---------------------- Before we really jump in, let's set up a couple of things in DevStack. This is the first real test that DevStack is working, so if you get errors from any of these commands, it's a sign that ``stack.sh`` didn't finish properly, or perhaps that you didn't run the ``openrc admin`` command at the end of the previous instructions. If you stop and restart DevStack via ``unstack.sh`` followed by ``stack.sh``, you have to rerun these steps. 1. For SSH access to the VMs we're going to create, we'll need a SSH keypair. Later on, we'll get OpenStack to install this keypair into VMs. Create one with:: $ openstack keypair create demo > ~/id_rsa_demo $ chmod 600 ~/id_rsa_demo 2. By default, DevStack security groups drop incoming traffic, but to test networking in a reasonable way we need to enable it. You only need to actually edit one particular security group, but DevStack creates multiple and it's somewhat difficult to figure out which one is important because all of them are named "default". So, the following adds rules to allow SSH and ICMP traffic into **every** security group:: $ for group in $(openstack security group list -f value -c ID); do \ openstack security group rule create --ingress --ethertype IPv4 --dst-port 22 --protocol tcp $group; \ openstack security group rule create --ingress --ethertype IPv4 --protocol ICMP $group; \ done 3. Later on, we're going to create some VMs and we'll need an operating system image to install. DevStack comes with a very simple image built-in, called "cirros", which works fine. We need to get the UUID for this image. Our later commands assume shell variable ``IMAGE_ID`` holds this UUID. You can set this by hand, e.g.:: $ openstack image list +--------------------------------------+--------------------------+--------+ | ID | Name | Status | +--------------------------------------+--------------------------+--------+ | 77f37d2c-3d6b-4e99-a01b-1fa5d78d1fa1 | cirros-0.3.5-x86_64-disk | active | +--------------------------------------+--------------------------+--------+ $ IMAGE_ID=73ca34f3-63c4-4c10-a62f-4540afc24eaa or by parsing CLI output:: $ IMAGE_ID=$(openstack image list -f value -c ID) .. note:: Your image ID will differ from the one above, as will every UUID in this tutorial. They will also change every time you run ``stack.sh``. The UUIDs are generated randomly. Shortening UUIDs ---------------- OpenStack, OVN, and Open vSwitch all really like UUIDs. These are great for uniqueness, but 36-character strings are terrible for readability. Statistically, just the first few characters are enough for uniqueness in small environments, so let's define a helper to make things more readable:: $ abbrev() { a='[0-9a-fA-F]' b=$a$a c=$b$b; sed "s/$b-$c-$c-$c-$c$c$c//g"; } You can use this as a filter to abbreviate UUIDs. For example, use it to abbreviate the above image list:: $ openstack image list -f yaml | abbrev - ID: 77f37d Name: cirros-0.3.5-x86_64-disk Status: active The command above also adds ``-f yaml`` to switch to YAML output format, because abbreviating UUIDs screws up the default table-based formatting and because YAML output doesn't produce wrap columns across lines and therefore is easier to cut and paste. Overview -------- Now that DevStack is ready, with OVN set up as the networking back-end, here's an overview of what we're going to do in the remainder of the demo, all via OpenStack: 1. Switching: Create an OpenStack network ``n1`` and VMs ``a`` and ``b`` attached to it. An OpenStack network is a virtual switch; it corresponds to an OVN logical switch. 2. Routing: Create a second OpenStack network ``n2`` and VM ``c`` attached to it, then connect it to network ``n1`` by creating an OpenStack router and attaching ``n1`` and ``n2`` to it. 3. Gateways: Make VMs ``a`` and ``b`` available via an external network. 4. IPv6: Add IPv6 addresses to our VMs to demonstrate OVN support for IPv6 routing. 5. ACLs: Add and modify OpenStack stateless and stateful rules in security groups. 6. DHCP: How it works in OVN. 7. Further directions: Adding more compute nodes. At each step, we will take a look at how the features in question work from OpenStack's Neutron networking layer at the top to the data plane layer at the bottom. From the highest to lowest level, these layers and the software components that connect them are: * OpenStack Neutron, which as the top level in the system is the authoritative source of the virtual network configuration. We will use OpenStack's ``openstack`` utility to observe and modify Neutron and other OpenStack configuration. * networking-ovn, the Neutron driver that interfaces with OVN and translates the internal Neutron representation of the virtual network into OVN's representation and pushes that representation down the OVN northbound database. In this tutorial it's rarely worth distinguishing Neutron from networking-ovn, so we usually don't break out this layer separately. * The OVN Northbound database, aka NB DB. This is an instance of OVSDB, a simple general-purpose database that is used for multiple purposes in Open vSwitch and OVN. The NB DB's schema is in terms of networking concepts such as switches and routers. The NB DB serves the purpose that in other systems might be filled by some kind of API; for example, in place of calling an API to create or delete a logical switch, networking-ovn performs these operations by inserting or deleting a row in the NB DB's Logical_Switch table. We will use OVN's ``ovn-nbctl`` utility to observe the NB DB. (We won't directly modify data at this layer or below. Because configuration trickles down from Neutron through the stack, the right way to make changes is to use the ``openstack`` utility or another OpenStack interface and then wait for them to percolate through to lower layers.) * The ovn-northd daemon, a program that runs centrally and translates the NB DB's network representation into the lower-level representation used by the OVN Southbound database in the next layer. The details of this daemon are usually not of interest, although without it OVN will not work, so this tutorial does not often mention it. * The OVN Southbound database, aka SB DB, which is also an OVSDB database. Its schema is very different from the NB DB. Instead of familiar networking concepts, the SB DB defines the network in terms of collections of match-action rules called "logical flows", which while similar in concept to OpenFlow flows use logical concepts, such as virtual machine instances, in place of physical concepts like physical Ethernet ports. We will use OVN's ``ovn-sbctl`` utility to observe the SB DB. * The ovn-controller daemon. A copy of ovn-controller runs on each hypervisor. It reads logical flows from the SB DB, translates them into OpenFlow flows, and sends them to Open vSwitch's ovs-vswitchd daemon. Like ovn-northd, usually the details of what this daemon are not of interest, even though it's important to the operation of the system. * ovs-vswitchd. This program runs on each hypervisor. It is the core of Open vSwitch, which processes packets according to the OpenFlow flows set up by ovn-controller. * Open vSwitch datapath. This is essentially a cache designed to accelerate packet processing. Open vSwitch includes a few different datapaths but OVN installations typically use one based on the Open vSwitch Linux kernel module. Switching --------- Switching is the basis of networking in the real world and in virtual networking as well. OpenStack calls its concept of a virtual switch a "network", and OVN calls its corresponding concept a "logical switch". In this step, we'll create an OpenStack network ``n1``, then create VMs ``a`` and ``b`` and attach them to ``n1``. Creating network ``n1`` ~~~~~~~~~~~~~~~~~~~~~~~ Let's start by creating the network:: $ openstack network create --provider-network-type geneve n1 OpenStack needs to know the subnets that a network serves. We inform it by creating subnet objects. To keep it simple, let's give our network a single subnet for the 10.1.1.0/24 network. We have to give it a name, in this case ``n1subnet``:: $ openstack subnet create --subnet-range 10.1.1.0/24 --network n1 n1subnet If you ask Neutron to show us the available networks, we see ``n1`` as well as the two networks that DevStack creates by default:: $ openstack network list -f yaml | abbrev - ID: 5b6baf Name: n1 Subnets: 5e67e7 - ID: c02c4d Name: private Subnets: d88a34, fd87f9 - ID: d1ac28 Name: public Subnets: 0b1e79, c87dc1 Neutron pushes this network setup down to the OVN northbound database. We can use ``ovn-nbctl show`` to see an overview of what's in the NB DB:: $ ovn-nbctl show | abbrev switch 5b3d5f (neutron-c02c4d) (aka private) port b256dd type: router router-port: lrp-b256dd port f264e7 type: router router-port: lrp-f264e7 switch 2579f4 (neutron-d1ac28) (aka public) port provnet-d1ac28 type: localnet addresses: ["unknown"] port ae9b52 type: router router-port: lrp-ae9b52 switch 3eb263 (neutron-5b6baf) (aka n1) router c59ad2 (neutron-9b057f) (aka router1) port lrp-ae9b52 mac: "fa:16:3e:b2:d2:67" networks: ["172.24.4.9/24", "2001:db8::b/64"] port lrp-b256dd mac: "fa:16:3e:35:33:db" networks: ["fdb0:5860:4ba8::1/64"] port lrp-f264e7 mac: "fa:16:3e:fc:c8:da" networks: ["10.0.0.1/26"] nat 80914c external ip: "172.24.4.9" logical ip: "10.0.0.0/26" type: "snat" This output shows that OVN has three logical switches, each of which corresponds to a Neutron network, and a logical router that corresponds to the Neutron router that DevStack creates by default. The logical switch that corresponds to our new network ``n1`` has no ports yet, because we haven't added any. The ``public`` and ``private`` networks that DevStack creates by default have router ports that connect to the logical router. Using ovn-northd, OVN translates the NB DB's high-level switch and router concepts into lower-level concepts of "logical datapaths" and logical flows. There's one logical datapath for each logical switch or router:: $ ovn-sbctl list datapath_binding | abbrev _uuid : 0ad69d external_ids : {logical-switch="5b3d5f", name="neutron-c02c4d", "name2"=private} tunnel_key : 1 _uuid : a8a758 external_ids : {logical-switch="3eb263", name="neutron-5b6baf", "name2"="n1"} tunnel_key : 4 _uuid : 191256 external_ids : {logical-switch="2579f4", name="neutron-d1ac28", "name2"=public} tunnel_key : 3 _uuid : b87bec external_ids : {logical-router="c59ad2", name="neutron-9b057f", "name2"="router1"} tunnel_key : 2 This output lists the NB DB UUIDs in external_ids:logical-switch and Neutron UUIDs in externals_ids:uuid. We can dive in deeper by viewing the OVN logical flows that implement a logical switch. Our new logical switch is a simple and almost pathological example given that it doesn't yet have any ports attached to it. We'll look at the details a bit later:: $ ovn-sbctl lflow-list n1 | abbrev Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: ingress table=0 (ls_in_port_sec_l2 ), priority=100 , match=(eth.src[40]), action=(drop;) table=0 (ls_in_port_sec_l2 ), priority=100 , match=(vlan.present), action=(drop;) ... Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: egress table=0 (ls_out_pre_lb ), priority=0 , match=(1), action=(next;) table=1 (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) ... We have one hypervisor (aka "compute node", in OpenStack parlance), which is the one where we're running all these commands. On this hypervisor, ovn-controller is translating OVN logical flows into OpenFlow flows ("physical flows"). It makes sense to go deeper, to see the OpenFlow flows that get generated from this datapath. By adding ``--ovs`` to the ``ovn-sbctl`` command, we can see OpenFlow flows listed just below their logical flows. We also need to use ``sudo`` because connecting to Open vSwitch is privileged. Go ahead and try it:: $ sudo ovn-sbctl --ovs lflow-list n1 | abbrev Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: ingress table=0 (ls_in_port_sec_l2 ), priority=100 , match=(eth.src[40]), action=(drop;) table=0 (ls_in_port_sec_l2 ), priority=100 , match=(vlan.present), action=(drop;) ... Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: egress table=0 (ls_out_pre_lb ), priority=0 , match=(1), action=(next;) table=1 (ls_out_pre_acl ), priority=0 , match=(1), action=(next;) ... You were probably disappointed: the output didn't change, and no OpenFlow flows were printed. That's because no OpenFlow flows are installed for this logical datapath, which in turn is because there are no VIFs for this logical datapath on the local hypervisor. For a better example, you can try ``ovn-sbctl --ovs`` on one of the other logical datapaths. Attaching VMs ~~~~~~~~~~~~~ A switch without any ports is not very interesting. Let's create a couple of VMs and attach them to the switch. Run the following commands, which create VMs named ``a`` and ``b`` and attaches them to our network ``n1`` with IP addresses 10.1.1.5 and 10.1.1.6, respectively. It is not actually necessary to manually assign IP address assignments, since OpenStack is perfectly happy to assign them itself from the subnet's IP address range, but predictable addresses are useful for our discussion:: $ openstack server create --nic net-id=n1,v4-fixed-ip=10.1.1.5 --flavor m1.nano --image $IMAGE_ID --key-name demo a $ openstack server create --nic net-id=n1,v4-fixed-ip=10.1.1.6 --flavor m1.nano --image $IMAGE_ID --key-name demo b These commands return before the VMs are really finished being built. You can run ``openstack server list`` a few times until each of them is shown in the state ACTIVE, which means that they're not just built but already running on the local hypervisor. These operations had the side effect of creating separate "port" objects, but without giving those ports any easy-to-read names. It'll be easier to deal with them later if we can refer to them by name, so let's name ``a``'s port ``ap`` and ``b``'s port ``bp``:: $ openstack port set --name ap $(openstack port list --server a -f value -c ID) $ openstack port set --name bp $(openstack port list --server b -f value -c ID) We'll need to refer to these ports' MAC addresses a few times, so let's put them in variables:: $ AP_MAC=$(openstack port show -f value -c mac_address ap) $ BP_MAC=$(openstack port show -f value -c mac_address bp) At this point you can log into the consoles of the VMs if you like. You can do that from the OpenStack web interface or get a direct URL to paste into a web browser using a command like:: $ openstack console url show -f yaml a (The option ``-f yaml`` keeps the URL in the output from being broken into noncontiguous pieces on a 80-column console.) The VMs don't have many tools in them but ``ping`` and ``ssh`` from one to the other should work fine. The VMs do not have any external network access or DNS configuration. Let's chase down what's changed in OVN. Start with the NB DB at the top of the system. It's clear that our logical switch now has the two logical ports attached to it:: $ ovn-nbctl show | abbrev ... switch 3eb263 (neutron-5b6baf) (aka n1) port c29d41 (aka bp) addresses: ["fa:16:3e:99:7a:17 10.1.1.6"] port 820c08 (aka ap) addresses: ["fa:16:3e:a9:4c:c7 10.1.1.5"] ... We can get some more details on each of these by looking at their NB DB records in the Logical_Switch_Port table. Each port has addressing information, port security enabled, and a pointer to DHCP configuration (which we'll look at much later in `DHCP`_):: $ ovn-nbctl list logical_switch_port ap bp | abbrev _uuid : ef17e5 addresses : ["fa:16:3e:a9:4c:c7 10.1.1.5"] dhcpv4_options : 165974 dhcpv6_options : [] dynamic_addresses : [] enabled : true external_ids : {"neutron:port_name"=ap} name : "820c08" options : {} parent_name : [] port_security : ["fa:16:3e:a9:4c:c7 10.1.1.5"] tag : [] tag_request : [] type : "" up : true _uuid : e8af12 addresses : ["fa:16:3e:99:7a:17 10.1.1.6"] dhcpv4_options : 165974 dhcpv6_options : [] dynamic_addresses : [] enabled : true external_ids : {"neutron:port_name"=bp} name : "c29d41" options : {} parent_name : [] port_security : ["fa:16:3e:99:7a:17 10.1.1.6"] tag : [] tag_request : [] type : "" up : true Now that the logical switch is less pathological, it's worth taking another look at the SB DB logical flow table. Try a command like this:: $ ovn-sbctl lflow-list n1 | abbrev | less -S and then glance through the flows. Packets that egress a VM into the logical switch travel through the flow table's ingress pipeline starting from table 0. At each table, the switch finds the highest-priority logical flow that matches and executes its actions, or if there's no matching flow then the packet is dropped. The ``ovn-sb``\(5) manpage gives all the details, but with a little thought it's possible to guess a lot without reading the manpage. For example, consider the flows in ingress pipeline table 0, which are the first flows encountered by a packet traversing the switch:: table=0 (ls_in_port_sec_l2 ), priority=100 , match=(eth.src[40]), action=(drop;) table=0 (ls_in_port_sec_l2 ), priority=100 , match=(vlan.present), action=(drop;) table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "820c08" && eth.src == {fa:16:3e:a9:4c:c7}), action=(next;) table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "c29d41" && eth.src == {fa:16:3e:99:7a:17}), action=(next;) The first two flows, with priority 100, immediately drop two kinds of invalid packets: those with a multicast or broadcast Ethernet source address (since multicast is only for packet destinations) and those with a VLAN tag (because OVN doesn't yet support VLAN tags inside logical networks). The next two flows implement L2 port security: they advance to the next table for packets with the correct Ethernet source addresses for their ingress ports. A packet that does not match any flow is implicitly dropped, so there's no need for flows to deal with mismatches. The logical flow table includes many other flows, some of which we will look at later. For now, it's most worth looking at ingress table 13:: table=13(ls_in_l2_lkup ), priority=100 , match=(eth.mcast), action=(outport = "_MC_flood"; output;) table=13(ls_in_l2_lkup ), priority=50 , match=(eth.dst == fa:16:3e:99:7a:17), action=(outport = "c29d41"; output;) table=13(ls_in_l2_lkup ), priority=50 , match=(eth.dst == fa:16:3e:a9:4c:c7), action=(outport = "820c08"; output;) The first flow in table 13 checks whether the packet is an Ethernet multicast or broadcast and, if so, outputs it to a special port that egresses to every logical port (other than the ingress port). Otherwise the packet is output to the port corresponding to its Ethernet destination address. Packets addressed to any other Ethernet destination are implicitly dropped. (It's common for an OVN logical switch to know all the MAC addresses supported by its logical ports, like this one. That's why there's no logic here for MAC learning or flooding packets to unknown MAC addresses. OVN does support unknown MAC handling but that's not in play in our example.) .. note:: If you're interested in the details for the multicast group, you can run a command like the following and then look at the row for the correct datapath:: $ ovn-sbctl find multicast_group name=_MC_flood | abbrev Now if you want to look at the OpenFlow flows, you can actually see them. For example, here's the beginning of the output that lists the first four logical flows, which we already looked at above, and their corresponding OpenFlow flows. If you want to know more about the syntax, the ``ovs-fields``\(7) manpage explains OpenFlow matches and ``ovs-ofctl``\(8) explains OpenFlow actions:: $ sudo ovn-sbctl --ovs lflow-list n1 | abbrev Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: ingress table=0 (ls_in_port_sec_l2 ), priority=100 , match=(eth.src[40]), action=(drop;) table=8 metadata=0x4,dl_src=01:00:00:00:00:00/01:00:00:00:00:00 actions=drop table=0 (ls_in_port_sec_l2 ), priority=100 , match=(vlan.present), action=(drop;) table=8 metadata=0x4,vlan_tci=0x1000/0x1000 actions=drop table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "820c08" && eth.src == {fa:16:3e:a9:4c:c7}), action=(next;) table=8 reg14=0x1,metadata=0x4,dl_src=fa:16:3e:a9:4c:c7 actions=resubmit(,9) table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "c29d41" && eth.src == {fa:16:3e:99:7a:17}), action=(next;) table=8 reg14=0x2,metadata=0x4,dl_src=fa:16:3e:99:7a:17 actions=resubmit(,9) ... Logical Tracing +++++++++++++++ Let's go a level deeper. So far, everything we've done has been fairly general. We can also look at something more specific: the path that a particular packet would take through OVN, logically, and Open vSwitch, physically. Let's use OVN's ovn-trace utility to see what happens to packets from a logical point of view. The ``ovn-trace``\(8) manpage has a lot of detail on how to do that, but let's just start by building up from a simple example. You can start with a command that just specifies the logical datapath, an input port, and nothing else; unspecified fields default to all-zeros. This doesn't do much:: $ ovn-trace n1 'inport == "ap"' ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2: no match (implicit drop) We see that the packet was dropped in logical table 0, "ls_in_port_sec_l2", the L2 port security stage (as we discussed earlier). That's because we didn't use the right Ethernet source address for ``a``. Let's see what happens if we do:: $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "ap" && eth.src == {fa:16:3e:a9:4c:c7}, priority 50, uuid 6dcc418a next; 13. ls_in_l2_lkup: no match (implicit drop) Now the packet passes through L2 port security and skips through several other tables until it gets dropped in the L2 lookup stage (because the destination is unknown). Let's add the Ethernet destination for ``b``:: $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$BP_MAC ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "ap" && eth.src == {fa:16:3e:a9:4c:c7}, priority 50, uuid 6dcc418a next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:99:7a:17, priority 50, uuid 57a4c46f outport = "bp"; output; egress(dp="n1", inport="ap", outport="bp") ------------------------------------------ 8. ls_out_port_sec_l2 (northd.c:3654): outport == "bp" && eth.dst == {fa:16:3e:99:7a:17}, priority 50, uuid 8aa6426d output; /* output to "bp", type "" */ You can see that in this case the packet gets properly switched from ``a`` to ``b``. Physical Tracing for Hypothetical Packets +++++++++++++++++++++++++++++++++++++++++ ovn-trace showed us how a hypothetical packet would travel through the system in a logical fashion, that is, without regard to how VMs are distributed across the physical network. This is a convenient representation for understanding how OVN is **supposed** to work abstractly, but sometimes we might want to know more about how it actually works in the real systems where it is running. For this, we can use the tracing tool that Open vSwitch provides, which traces a hypothetical packet through the OpenFlow tables. We can actually get two levels of detail. Let's start with the version that's easier to interpret, by physically tracing a packet that looks like the one we logically traced before. One obstacle is that we need to know the OpenFlow port number of the input port. One way to do that is to look for a port whose "attached-mac" is the one we expect and print its ofport number:: $ AP_PORT=$(ovs-vsctl --bare --columns=ofport find interface external-ids:attached-mac=\"$AP_MAC\") $ echo $AP_PORT 3 (You could also just do a plain ``ovs-vsctl list interface`` and then look through for the right row and pick its ``ofport`` value.) Now we can feed this input port number into ``ovs-appctl ofproto/trace`` along with the correct Ethernet source and destination addresses and get a physical trace:: $ sudo ovs-appctl ofproto/trace br-int in_port=$AP_PORT,dl_src=$AP_MAC,dl_dst=$BP_MAC Flow: in_port=3,vlan_tci=0x0000,dl_src=fa:16:3e:a9:4c:c7,dl_dst=fa:16:3e:99:7a:17,dl_type=0x0000 bridge("br-int") ---------------- 0. in_port=3, priority 100 set_field:0x8->reg13 set_field:0x9->reg11 set_field:0xa->reg12 set_field:0x4->metadata set_field:0x1->reg14 resubmit(,8) 8. reg14=0x1,metadata=0x4,dl_src=fa:16:3e:a9:4c:c7, priority 50, cookie 0x6dcc418a resubmit(,9) 9. metadata=0x4, priority 0, cookie 0x8fe8689e resubmit(,10) 10. metadata=0x4, priority 0, cookie 0x719549d1 resubmit(,11) 11. metadata=0x4, priority 0, cookie 0x39c99e6f resubmit(,12) 12. metadata=0x4, priority 0, cookie 0x838152a3 resubmit(,13) 13. metadata=0x4, priority 0, cookie 0x918259e3 resubmit(,14) 14. metadata=0x4, priority 0, cookie 0xcad14db2 resubmit(,15) 15. metadata=0x4, priority 0, cookie 0x7834d912 resubmit(,16) 16. metadata=0x4, priority 0, cookie 0x87745210 resubmit(,17) 17. metadata=0x4, priority 0, cookie 0x34951929 resubmit(,18) 18. metadata=0x4, priority 0, cookie 0xd7a8c9fb resubmit(,19) 19. metadata=0x4, priority 0, cookie 0xd02e9578 resubmit(,20) 20. metadata=0x4, priority 0, cookie 0x42d35507 resubmit(,21) 21. metadata=0x4,dl_dst=fa:16:3e:99:7a:17, priority 50, cookie 0x57a4c46f set_field:0x2->reg15 resubmit(,32) 32. priority 0 resubmit(,33) 33. reg15=0x2,metadata=0x4, priority 100 set_field:0xb->reg13 set_field:0x9->reg11 set_field:0xa->reg12 resubmit(,34) 34. priority 0 set_field:0->reg0 set_field:0->reg1 set_field:0->reg2 set_field:0->reg3 set_field:0->reg4 set_field:0->reg5 set_field:0->reg6 set_field:0->reg7 set_field:0->reg8 set_field:0->reg9 resubmit(,40) 40. metadata=0x4, priority 0, cookie 0xde9f3899 resubmit(,41) 41. metadata=0x4, priority 0, cookie 0x74074eff resubmit(,42) 42. metadata=0x4, priority 0, cookie 0x7789c8b1 resubmit(,43) 43. metadata=0x4, priority 0, cookie 0xa6b002c0 resubmit(,44) 44. metadata=0x4, priority 0, cookie 0xaeab2b45 resubmit(,45) 45. metadata=0x4, priority 0, cookie 0x290cc4d4 resubmit(,46) 46. metadata=0x4, priority 0, cookie 0xa3223b88 resubmit(,47) 47. metadata=0x4, priority 0, cookie 0x7ac2132e resubmit(,48) 48. reg15=0x2,metadata=0x4,dl_dst=fa:16:3e:99:7a:17, priority 50, cookie 0x8aa6426d resubmit(,64) 64. priority 0 resubmit(,65) 65. reg15=0x2,metadata=0x4, priority 100 output:4 Final flow: reg11=0x9,reg12=0xa,reg13=0xb,reg14=0x1,reg15=0x2,metadata=0x4,in_port=3,vlan_tci=0x0000,dl_src=fa:16:3e:a9:4c:c7,dl_dst=fa:16:3e:99:7a:17,dl_type=0x0000 Megaflow: recirc_id=0,ct_state=-new-est-rel-rpl-inv-trk,ct_label=0/0x1,in_port=3,vlan_tci=0x0000/0x1000,dl_src=fa:16:3e:a9:4c:c7,dl_dst=fa:16:3e:99:7a:17,dl_type=0x0000 Datapath actions: 4 There's a lot there, which you can read through if you like, but the important part is:: 65. reg15=0x2,metadata=0x4, priority 100 output:4 which means that the packet is ultimately being output to OpenFlow port 4. That's port ``b``, which you can confirm with:: $ sudo ovs-vsctl find interface ofport=4 _uuid : 840a5aca-ea8d-4c16-a11b-a94e0f408091 admin_state : up bfd : {} bfd_status : {} cfm_fault : [] cfm_fault_status : [] cfm_flap_count : [] cfm_health : [] cfm_mpid : [] cfm_remote_mpids : [] cfm_remote_opstate : [] duplex : full error : [] external_ids : {attached-mac="fa:16:3e:99:7a:17", iface-id="c29d4120-20a4-4c44-bd83-8d91f5f447fd", iface-status=active, vm-id="2db969ca-ca2a-4d9a-b49e-f287d39c5645"} ifindex : 9 ingress_policing_burst: 0 ingress_policing_rate: 0 lacp_current : [] link_resets : 1 link_speed : 10000000 link_state : up lldp : {} mac : [] mac_in_use : "fe:16:3e:99:7a:17" mtu : 1500 mtu_request : [] name : "tapc29d4120-20" ofport : 4 ofport_request : [] options : {} other_config : {} statistics : {collisions=0, rx_bytes=4254, rx_crc_err=0, rx_dropped=0, rx_errors=0, rx_frame_err=0, rx_over_err=0, rx_packets=39, tx_bytes=4188, tx_dropped=0, tx_errors=0, tx_packets=39} status : {driver_name=tun, driver_version="1.6", firmware_version=""} type : "" or:: $ BP_PORT=$(ovs-vsctl --bare --columns=ofport find interface external-ids:attached-mac=\"$BP_MAC\") $ echo $BP_PORT 4 Physical Tracing for Real Packets +++++++++++++++++++++++++++++++++ In the previous sections we traced a hypothetical L2 packet, one that's honestly not very realistic: we didn't even supply an Ethernet type, so it defaulted to zero, which isn't anything one would see on a real network. We could refine our packet so that it becomes a more realistic TCP or UDP or ICMP, etc. packet, but let's try a different approach: working from a real packet. Pull up a console for VM ``a`` and start ``ping 10.1.1.6``, then leave it running for the rest of our experiment. Now go back to your DevStack session and run:: $ sudo watch ovs-dpctl dump-flows We're working with a new program. ovn-dpctl is an interface to Open vSwitch datapaths, in this case to the Linux kernel datapath. Its ``dump-flows`` command displays the contents of the in-kernel flow cache, and by running it under the ``watch`` program we see a new snapshot of the flow table every 2 seconds. Look through the output for a flow that begins with ``recirc_id(0)`` and matches the Ethernet source address for ``a``. There is one flow per line, but the lines are very long, so it's easier to read if you make the window very wide. This flow's packet counter should be increasing at a rate of 1 packet per second. It looks something like this:: recirc_id(0),in_port(3),eth(src=fa:16:3e:f5:2a:90),eth_type(0x0800),ipv4(src=10.1.1.5,frag=no), packets:388, bytes:38024, used:0.977s, actions:ct(zone=8),recirc(0x18) .. note:: Flows in the datapath can expire quickly and the ``watch`` command mentioned above may be too slow to catch it. If that is your case, stop the ``ping 10.1.1.6`` session and re-start it a few seconds after this command:: $ sudo conntrack -F ; rm -f /tmp/flows.txt ; \ for _ in $(seq 100) ; do \ sudo ovs-dpctl dump-flows >> /tmp/flows.txt ; \ sleep 0.1 ; done Then, look for ``recirc_id(0)`` in flows.txt after ping command was issued:: $ sort --uniq /tmp/flows.txt | grep zone We can hand the first part of this (everything up to the first space) to ``ofproto/trace``, and it will tell us what happens:: $ sudo ovs-appctl ofproto/trace 'recirc_id(0),in_port(3),eth(src=fa:16:3e:a9:4c:c7),eth_type(0x0800),ipv4(src=10.1.1.5,dst=10.1.0.0/255.255.0.0,frag=no)' Flow: ip,in_port=3,vlan_tci=0x0000,dl_src=fa:16:3e:a9:4c:c7,dl_dst=00:00:00:00:00:00,nw_src=10.1.1.5,nw_dst=10.1.0.0,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0 bridge("br-int") ---------------- 0. in_port=3, priority 100 set_field:0x8->reg13 set_field:0x9->reg11 set_field:0xa->reg12 set_field:0x4->metadata set_field:0x1->reg14 resubmit(,8) 8. reg14=0x1,metadata=0x4,dl_src=fa:16:3e:a9:4c:c7, priority 50, cookie 0x6dcc418a resubmit(,9) 9. ip,reg14=0x1,metadata=0x4,dl_src=fa:16:3e:a9:4c:c7,nw_src=10.1.1.5, priority 90, cookie 0x343af48c resubmit(,10) 10. metadata=0x4, priority 0, cookie 0x719549d1 resubmit(,11) 11. ip,metadata=0x4, priority 100, cookie 0x46c089e6 load:0x1->NXM_NX_XXREG0[96] resubmit(,12) 12. metadata=0x4, priority 0, cookie 0x838152a3 resubmit(,13) 13. ip,reg0=0x1/0x1,metadata=0x4, priority 100, cookie 0xd1941634 ct(table=22,zone=NXM_NX_REG13[0..15]) drop Final flow: ip,reg0=0x1,reg11=0x9,reg12=0xa,reg13=0x8,reg14=0x1,metadata=0x4,in_port=3,vlan_tci=0x0000,dl_src=fa:16:3e:a9:4c:c7,dl_dst=00:00:00:00:00:00,nw_src=10.1.1.5,nw_dst=10.1.0.0,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0 Megaflow: recirc_id=0,ip,in_port=3,vlan_tci=0x0000/0x1000,dl_src=fa:16:3e:a9:4c:c7,nw_src=10.1.1.5,nw_dst=10.1.0.0/16,nw_frag=no Datapath actions: ct(zone=8),recirc(0xb) .. note:: Be careful cutting and pasting ``ovs-dpctl dump-flows`` output into ``ofproto/trace`` because the latter has terrible error reporting. If you add an extra line break, etc., it will likely give you a useless error message. There's no ``output`` action in the output, but there are ``ct`` and ``recirc`` actions (which you can see in the ``Datapath actions`` at the end). The ``ct`` action tells the kernel to pass the packet through the kernel connection tracking for firewalling purposes and the ``recirc`` says to go back to the flow cache for another pass based on the firewall results. The ``0xb`` value inside the ``recirc`` gives us a hint to look at the kernel flows for a cached flow with ``recirc_id(0xb)``. Indeed, there is one:: recirc_id(0xb),in_port(3),ct_state(-new+est-rel-rpl-inv+trk),ct_label(0/0x1),eth(src=fa:16:3e:a9:4c:c7,dst=fa:16:3e:99:7a:17),eth_type(0x0800),ipv4(dst=10.1.1.4/255.255.255.252,frag=no), packets:171, bytes:16758, used:0.271s, actions:ct(zone=11),recirc(0xc) We can then repeat our command with the match part of this kernel flow:: $ sudo ovs-appctl ofproto/trace 'recirc_id(0xb),in_port(3),ct_state(-new+est-rel-rpl-inv+trk),ct_label(0/0x1),eth(src=fa:16:3e:a9:4c:c7,dst=fa:16:3e:99:7a:17),eth_type(0x0800),ipv4(dst=10.1.1.4/255.255.255.252,frag=no)' ... Datapath actions: ct(zone=11),recirc(0xc) In other words, the flow passes through the connection tracker a second time. The first time was for ``a``'s outgoing firewall; this second time is for ``b``'s incoming firewall. Again, we continue tracing with ``recirc_id(0xc)``:: $ sudo ovs-appctl ofproto/trace 'recirc_id(0xc),in_port(3),ct_state(-new+est-rel-rpl-inv+trk),ct_label(0/0x1),eth(src=fa:16:3e:a9:4c:c7,dst=fa:16:3e:99:7a:17),eth_type(0x0800),ipv4(dst=10.1.1.6,proto=1,frag=no)' ... Datapath actions: 4 It took multiple hops, but we finally came to the end of the line where the packet was output to ``b`` after passing through both firewalls. The port number here is a datapath port number, which is usually different from an OpenFlow port number. To check that it is ``b``'s port, we first list the datapath ports to get the name corresponding to the port number:: $ sudo ovs-dpctl show system@ovs-system: lookups: hit:1994 missed:56 lost:0 flows: 6 masks: hit:2340 total:4 hit/pkt:1.14 port 0: ovs-system (internal) port 1: br-int (internal) port 2: br-ex (internal) port 3: tap820c0888-13 port 4: tapc29d4120-20 and then confirm that this is the port we think it is with a command like this:: $ ovs-vsctl --columns=external-ids list interface tapc29d4120-20 external_ids : {attached-mac="fa:16:3e:99:7a:17", iface-id="c29d4120-20a4-4c44-bd83-8d91f5f447fd", iface-status=active, vm-id="2db969ca-ca2a-4d9a-b49e-f287d39c5645"} Finally, we can relate the OpenFlow flows from our traces back to OVN logical flows. For individual flows, cut and paste a "cookie" value from ``ofproto/trace`` output into ``ovn-sbctl lflow-list``, e.g.:: $ ovn-sbctl lflow-list 0x6dcc418a|abbrev Datapath: "neutron-5b6baf" aka "n1" (a8a758) Pipeline: ingress table=0 (ls_in_port_sec_l2 ), priority=50 , match=(inport == "820c08" && eth.src == {fa:16:3e:a9:4c:c7}), action=(next;) Or, you can pipe ``ofproto/trace`` output through ``ovn-detrace`` to annotate every flow:: $ sudo ovs-appctl ofproto/trace 'recirc_id(0xc),in_port(3),ct_state(-new+est-rel-rpl-inv+trk),ct_label(0/0x1),eth(src=fa:16:3e:a9:4c:c7,dst=fa:16:3e:99:7a:17),eth_type(0x0800),ipv4(dst=10.1.1.6,proto=1,frag=no)' | ovn-detrace ... Routing ------- Previously we set up a pair of VMs ``a`` and ``b`` on a network ``n1`` and demonstrated how packets make their way between them. In this step, we'll set up a second network ``n2`` with a new VM ``c``, connect a router ``r`` to both networks, and demonstrate how routing works in OVN. There's nothing really new for the network and the VM so let's just go ahead and create them:: $ openstack network create --provider-network-type geneve n2 $ openstack subnet create --subnet-range 10.1.2.0/24 --network n2 n2subnet $ openstack server create --nic net-id=n2,v4-fixed-ip=10.1.2.7 --flavor m1.nano --image $IMAGE_ID --key-name demo c $ openstack port set --name cp $(openstack port list --server c -f value -c ID) $ CP_MAC=$(openstack port show -f value -c mac_address cp) The new network ``n2`` is not yet connected to ``n1`` in any way. You can try tracing a packet from ``a`` to see, for example, that it doesn’t make it to ``c``. Instead, it will end up as ``multicast unknown`` in ``n1``:: $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$CP_MAC ... Now create an OpenStack router and connect it to ``n1`` and ``n2``:: $ openstack router create r $ openstack router add subnet r n1subnet $ openstack router add subnet r n2subnet Now ``a``, ``b``, and ``c`` should all be able to reach other. You can get some verification that routing is taking place by running you ``ping`` between ``c`` and one of the other VMs: the reported TTL should be one less than between ``a`` and ``b`` (63 instead of 64). Observe via ``ovn-nbctl`` the new OVN logical switch and router and then ports that connect them together:: $ ovn-nbctl show|abbrev ... switch f51234 (neutron-332346) (aka n2) port 82b983 type: router router-port: lrp-82b983 port 2e585f (aka cp) addresses: ["fa:16:3e:89:f2:36 10.1.2.7"] switch 3eb263 (neutron-5b6baf) (aka n1) port c29d41 (aka bp) addresses: ["fa:16:3e:99:7a:17 10.1.1.6"] port 820c08 (aka ap) addresses: ["fa:16:3e:a9:4c:c7 10.1.1.5"] port 17d870 type: router router-port: lrp-17d870 ... router dde06c (neutron-f88ebc) (aka r) port lrp-82b983 mac: "fa:16:3e:19:9f:46" networks: ["10.1.2.1/24"] port lrp-17d870 mac: "fa:16:3e:f6:e2:8f" networks: ["10.1.1.1/24"] We have not yet looked at the logical flows for an OVN logical router. You might find it of interest to look at them on your own:: $ ovn-sbctl lflow-list r | abbrev | less -S ... Let's grab the ``n1subnet`` router porter MAC address to simplify later commands:: $ N1SUBNET_MAC=$(ovn-nbctl --bare --columns=mac find logical_router_port networks=10.1.1.1/24) Let's see what happens at the logical flow level for an ICMP packet from ``a`` to ``c``. This generates a long trace but an interesting one, so we'll look at it bit by bit. The first three stanzas in the output show the packet's ingress into ``n1`` and processing through the firewall on that side (via the "ct_next" connection-tracking action), and then the selection of the port that leads to router ``r`` as the output port:: $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$N1SUBNET_MAC' && ip4.src == 10.1.1.5 && ip4.dst == 10.1.2.7 && ip.ttl == 64 && icmp4.type == 8' ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "ap" && eth.src == {fa:16:3e:a9:4c:c7}, priority 50, uuid 6dcc418a next; 1. ls_in_port_sec_ip (northd.c:2364): inport == "ap" && eth.src == fa:16:3e:a9:4c:c7 && ip4.src == {10.1.1.5}, priority 90, uuid 343af48c next; 3. ls_in_pre_acl (northd.c:2646): ip, priority 100, uuid 46c089e6 reg0[0] = 1; next; 5. ls_in_pre_stateful (northd.c:2764): reg0[0] == 1, priority 100, uuid d1941634 ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 6. ls_in_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (inport == "ap" && ip4), priority 2002, uuid a12b39f0 next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:f6:e2:8f, priority 50, uuid c43ead31 outport = "17d870"; output; egress(dp="n1", inport="ap", outport="17d870") ---------------------------------------------- 1. ls_out_pre_acl (northd.c:2626): ip && outport == "17d870", priority 110, uuid 60395450 next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "17d870", priority 50, uuid 91b5cab0 output; /* output to "17d870", type "patch" */ The next two stanzas represent processing through logical router ``r``. The processing in table 5 is the core of the routing implementation: it recognizes that the packet is destined for an attached subnet, decrements the TTL and updates the Ethernet source address. Table 6 then selects the Ethernet destination address based on the IP destination. The packet then passes to switch ``n2`` via an OVN "logical patch port":: ingress(dp="r", inport="lrp-17d870") ------------------------------------ 0. lr_in_admission (northd.c:4071): eth.dst == fa:16:3e:f6:e2:8f && inport == "lrp-17d870", priority 50, uuid fa5270b0 next; 5. lr_in_ip_routing (northd.c:3782): ip4.dst == 10.1.2.0/24, priority 49, uuid 5f9d469f ip.ttl--; reg0 = ip4.dst; reg1 = 10.1.2.1; eth.src = fa:16:3e:19:9f:46; outport = "lrp-82b983"; flags.loopback = 1; next; 6. lr_in_arp_resolve (northd.c:5088): outport == "lrp-82b983" && reg0 == 10.1.2.7, priority 100, uuid 03d506d3 eth.dst = fa:16:3e:89:f2:36; next; 8. lr_in_arp_request (northd.c:5260): 1, priority 0, uuid 6dacdd82 output; egress(dp="r", inport="lrp-17d870", outport="lrp-82b983") --------------------------------------------------------- 3. lr_out_delivery (northd.c:5288): outport == "lrp-82b983", priority 100, uuid 00bea4f2 output; /* output to "lrp-82b983", type "patch" */ Finally the logical switch for ``n2`` runs through the same logic as ``n1`` and the packet is delivered to VM ``c``:: ingress(dp="n2", inport="82b983") --------------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "82b983", priority 50, uuid 9a789e06 next; 3. ls_in_pre_acl (northd.c:2624): ip && inport == "82b983", priority 110, uuid ab52f21a next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:89:f2:36, priority 50, uuid dcafb3e9 outport = "cp"; output; egress(dp="n2", inport="82b983", outport="cp") ---------------------------------------------- 1. ls_out_pre_acl (northd.c:2648): ip, priority 100, uuid cd9cfa74 reg0[0] = 1; next; 2. ls_out_pre_stateful (northd.c:2766): reg0[0] == 1, priority 100, uuid 9e8e22c5 ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 4. ls_out_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (outport == "cp" && ip4 && ip4.src == $as_ip4_0fc1b6cf_f925_49e6_8f00_6dd13beca9dc), priority 2002, uuid a746fa0d next; 7. ls_out_port_sec_ip (northd.c:2364): outport == "cp" && eth.dst == fa:16:3e:89:f2:36 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.1.2.7}, priority 90, uuid 4d9862b5 next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "cp" && eth.dst == {fa:16:3e:89:f2:36}, priority 50, uuid 0242cdc3 output; /* output to "cp", type "" */ Physical Tracing ~~~~~~~~~~~~~~~~ It's possible to use ``ofproto/trace``, just as before, to trace a packet through OpenFlow tables, either for a hypothetical packet or one that you get from a real test case using ``ovs-dpctl``. The process is just the same as before and the output is almost the same, too. Using a router doesn't actually introduce any interesting new wrinkles, so we'll skip over this for this case and for the remainder of the tutorial, but you can follow the steps on your own if you like. Adding a Gateway ---------------- The VMs that we've created can access each other but they are isolated from the physical world. In OpenStack, the dominant way to connect a VM to external networks is by creating what is called a "floating IP address", which uses network address translation to connect an external address to an internal one. DevStack created a pair of networks named "private" and "public". To use a floating IP address from a VM, we first add a port to the VM with an IP address from the "private" network, then we create a floating IP address on the "public" network, then we associate the port with the floating IP address. Let's add a new VM ``d`` with a floating IP:: $ openstack server create --nic net-id=private --flavor m1.nano --image $IMAGE_ID --key-name demo d $ openstack port set --name dp $(openstack port list --server d -f value -c ID) $ DP_MAC=$(openstack port show -f value -c mac_address dp) $ openstack floating ip create --floating-ip-address 172.24.4.8 public $ openstack server add floating ip d 172.24.4.8 (We specified a particular floating IP address to make the examples easier to follow, but without that OpenStack will automatically allocate one.) It's also necessary to configure the "public" network because DevStack does not do it automatically:: $ sudo ip link set br-ex up $ sudo ip addr add 172.24.4.1/24 dev br-ex Now you should be able to "ping" VM ``d`` from the OpenStack host:: $ ping 172.24.4.8 PING 172.24.4.8 (172.24.4.8) 56(84) bytes of data. 64 bytes from 172.24.4.8: icmp_seq=1 ttl=63 time=56.0 ms 64 bytes from 172.24.4.8: icmp_seq=2 ttl=63 time=1.44 ms 64 bytes from 172.24.4.8: icmp_seq=3 ttl=63 time=1.04 ms 64 bytes from 172.24.4.8: icmp_seq=4 ttl=63 time=0.403 ms ^C --- 172.24.4.8 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3003ms rtt min/avg/max/mdev = 0.403/14.731/56.028/23.845 ms You can also SSH in with the key that we created during setup:: $ ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ -i ~/id_rsa_demo cirros@172.24.4.8 Let's dive in and see how this gets implemented in OVN. First, the relevant parts of the NB DB for the "public" and "private" networks and the router between them:: $ ovn-nbctl show | abbrev switch 2579f4 (neutron-d1ac28) (aka public) port provnet-d1ac28 type: localnet addresses: ["unknown"] port ae9b52 type: router router-port: lrp-ae9b52 switch 5b3d5f (neutron-c02c4d) (aka private) port b256dd type: router router-port: lrp-b256dd port f264e7 type: router router-port: lrp-f264e7 port cae25b (aka dp) addresses: ["fa:16:3e:c1:f5:a2 10.0.0.6 fdb0:5860:4ba8:0:f816:3eff:fec1:f5a2"] ... router c59ad2 (neutron-9b057f) (aka router1) port lrp-ae9b52 mac: "fa:16:3e:b2:d2:67" networks: ["172.24.4.9/24", "2001:db8::b/64"] port lrp-b256dd mac: "fa:16:3e:35:33:db" networks: ["fdb0:5860:4ba8::1/64"] port lrp-f264e7 mac: "fa:16:3e:fc:c8:da" networks: ["10.0.0.1/26"] nat 788c6d external ip: "172.24.4.8" logical ip: "10.0.0.6" type: "dnat_and_snat" nat 80914c external ip: "172.24.4.9" logical ip: "10.0.0.0/26" type: "snat" ... What we see is: * VM ``d`` is on the "private" switch under its private IP address 10.0.0.6. The "private" switch is connected to "router1" via two router ports (one for IPv4, one for IPv6). * The "public" switch is connected to "router1" and to the physical network via a "localnet" port. * "router1" is in the middle between "private" and "public". In addition to the router ports that connect to these switches, it has "nat" entries that direct network address translation. The translation between floating IP address 172.24.4.8 and private address 10.0.0.6 makes perfect sense. When the NB DB gets translated into logical flows at the southbound layer, the "nat" entries get translated into IP matches that then invoke "ct_snat" and "ct_dnat" actions. The details are intricate, but you can get some of the idea by just looking for relevant flows:: $ ovn-sbctl lflow-list router1 | abbrev | grep nat | grep -E '172.24.4.8' table=3 (lr_in_unsnat ), priority=100 , match=(ip && ip4.dst == 172.24.4.8 && inport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52")), action=(ct_snat;) table=3 (lr_in_unsnat ), priority=50 , match=(ip && ip4.dst == 172.24.4.8), action=(reg9[0] = 1; next;) table=4 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.24.4.8 && inport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52")), action=(ct_dnat(10.0.0.6);) table=4 (lr_in_dnat ), priority=50 , match=(ip && ip4.dst == 172.24.4.8), action=(reg9[0] = 1; next;) table=1 (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.6 && outport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52")), action=(ct_snat(172.24.4.8);) Let's take a look at how a packet passes through this whole gauntlet. The first two stanzas just show the packet traveling through the "public" network and being forwarded to the "router1" network:: $ ovn-trace public 'inport == "provnet-d1ac2896-18a7-4bca-8f46-b21e2370e5b1" && eth.src == 00:01:02:03:04:05 && eth.dst == fa:16:3e:b2:d2:67 && ip4.src == 172.24.4.1 && ip4.dst == 172.24.4.8 && ip.ttl == 64 && icmp4.type==8' ... ingress(dp="public", inport="provnet-d1ac28") --------------------------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "provnet-d1ac28", priority 50, uuid 8d86fb06 next; 10. ls_in_arp_rsp (northd.c:3266): inport == "provnet-d1ac28", priority 100, uuid 21313eff next; 13. ls_in_l2_lkup (northd.c:3571): eth.dst == fa:16:3e:b2:d2:67 && is_chassis_resident("cr-lrp-ae9b52"), priority 50, uuid 7f28f51f outport = "ae9b52"; output; egress(dp="public", inport="provnet-d1ac28", outport="ae9b52") -------------------------------------------------------------- 8. ls_out_port_sec_l2 (northd.c:3654): outport == "ae9b52", priority 50, uuid 72fea396 output; /* output to "ae9b52", type "patch" */ In "router1", first the ``ct_snat`` action without an argument attempts to "un-SNAT" the packet. ovn-trace treats this as a no-op, because it doesn't have any state for tracking connections. As an alternative, it invokes ``ct_dnat(10.0.0.6)`` to NAT the destination IP:: ingress(dp="router1", inport="lrp-ae9b52") ------------------------------------------ 0. lr_in_admission (northd.c:4071): eth.dst == fa:16:3e:b2:d2:67 && inport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52"), priority 50, uuid 8c6945c2 next; 3. lr_in_unsnat (northd.c:4591): ip && ip4.dst == 172.24.4.8 && inport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52"), priority 100, uuid e922f541 ct_snat; ct_snat /* assuming no un-snat entry, so no change */ ----------------------------------------------------- 4. lr_in_dnat (northd.c:4649): ip && ip4.dst == 172.24.4.8 && inport == "lrp-ae9b52" && is_chassis_resident("cr-lrp-ae9b52"), priority 100, uuid 02f41b79 ct_dnat(10.0.0.6); Still in "router1", the routing and output steps transmit the packet to the "private" network:: ct_dnat(ip4.dst=10.0.0.6) ------------------------- 5. lr_in_ip_routing (northd.c:3782): ip4.dst == 10.0.0.0/26, priority 53, uuid 86e005b0 ip.ttl--; reg0 = ip4.dst; reg1 = 10.0.0.1; eth.src = fa:16:3e:fc:c8:da; outport = "lrp-f264e7"; flags.loopback = 1; next; 6. lr_in_arp_resolve (northd.c:5088): outport == "lrp-f264e7" && reg0 == 10.0.0.6, priority 100, uuid 2963d67c eth.dst = fa:16:3e:c1:f5:a2; next; 8. lr_in_arp_request (northd.c:5260): 1, priority 0, uuid eea419b7 output; egress(dp="router1", inport="lrp-ae9b52", outport="lrp-f264e7") --------------------------------------------------------------- 3. lr_out_delivery (northd.c:5288): outport == "lrp-f264e7", priority 100, uuid 42dadc23 output; /* output to "lrp-f264e7", type "patch" */ In the "private" network, the packet passes through VM ``d``'s firewall and is output to ``d``:: ingress(dp="private", inport="f264e7") -------------------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "f264e7", priority 50, uuid 5b721214 next; 3. ls_in_pre_acl (northd.c:2624): ip && inport == "f264e7", priority 110, uuid 5bdc3209 next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:c1:f5:a2, priority 50, uuid 7957f80f outport = "dp"; output; egress(dp="private", inport="f264e7", outport="dp") --------------------------------------------------- 1. ls_out_pre_acl (northd.c:2648): ip, priority 100, uuid 4981c79d reg0[0] = 1; next; 2. ls_out_pre_stateful (northd.c:2766): reg0[0] == 1, priority 100, uuid 247e02eb ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 4. ls_out_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (outport == "dp" && ip4 && ip4.src == 0.0.0.0/0 && icmp4), priority 2002, uuid b860fc9f next; 7. ls_out_port_sec_ip (northd.c:2364): outport == "dp" && eth.dst == fa:16:3e:c1:f5:a2 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.0.0.6}, priority 90, uuid 15655a98 next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "dp" && eth.dst == {fa:16:3e:c1:f5:a2}, priority 50, uuid 5916f94b output; /* output to "dp", type "" */ IPv6 ---- OVN supports IPv6 logical routing. Let's try it out. The first step is to add an IPv6 subnet to networks ``n1`` and ``n2``, then attach those subnets to our router ``r``. As usual, though OpenStack can assign addresses itself, we use fixed ones to make the discussion easier:: $ openstack subnet create --ip-version 6 --subnet-range fc11::/64 --network n1 n1subnet6 $ openstack subnet create --ip-version 6 --subnet-range fc22::/64 --network n2 n2subnet6 $ openstack router add subnet r n1subnet6 $ openstack router add subnet r n2subnet6 Then we add an IPv6 address to each of our VMs:: $ A_PORT_ID=$(openstack port list --server a -f value -c ID) $ openstack port set --fixed-ip subnet=n1subnet6,ip-address=fc11::5 $A_PORT_ID $ B_PORT_ID=$(openstack port list --server b -f value -c ID) $ openstack port set --fixed-ip subnet=n1subnet6,ip-address=fc11::6 $B_PORT_ID $ C_PORT_ID=$(openstack port list --server c -f value -c ID) $ openstack port set --fixed-ip subnet=n2subnet6,ip-address=fc22::7 $C_PORT_ID At least for me, the new IPv6 addresses didn't automatically get propagated into the VMs. To do it by hand, pull up the console for ``a`` and run:: $ sudo ip addr add fc11::5/64 dev eth0 $ sudo ip route add via fc11::1 Then in ``b``:: $ sudo ip addr add fc11::6/64 dev eth0 $ sudo ip route add via fc11::1 Finally in ``c``:: $ sudo ip addr add fc22::7/64 dev eth0 $ sudo ip route add via fc22::1 Now you should have working IPv6 routing through router ``r``. The relevant parts of the NB DB look like the following. The interesting parts are the new ``fc11::`` and ``fc22::`` addresses on the ports in ``n1`` and ``n2`` and the new IPv6 router ports in ``r``:: $ ovn-nbctl show | abbrev ... switch f51234 (neutron-332346) (aka n2) port 1a8162 type: router router-port: lrp-1a8162 port 82b983 type: router router-port: lrp-82b983 port 2e585f (aka cp) addresses: ["fa:16:3e:89:f2:36 10.1.2.7 fc22::7"] switch 3eb263 (neutron-5b6baf) (aka n1) port ad952e type: router router-port: lrp-ad952e port c29d41 (aka bp) addresses: ["fa:16:3e:99:7a:17 10.1.1.6 fc11::6"] port 820c08 (aka ap) addresses: ["fa:16:3e:a9:4c:c7 10.1.1.5 fc11::5"] port 17d870 type: router router-port: lrp-17d870 ... router dde06c (neutron-f88ebc) (aka r) port lrp-1a8162 mac: "fa:16:3e:06:de:ad" networks: ["fc22::1/64"] port lrp-82b983 mac: "fa:16:3e:19:9f:46" networks: ["10.1.2.1/24"] port lrp-ad952e mac: "fa:16:3e:ef:2f:8b" networks: ["fc11::1/64"] port lrp-17d870 mac: "fa:16:3e:f6:e2:8f" networks: ["10.1.1.1/24"] Try tracing a packet from ``a`` to ``c``. The results correspond closely to those for IPv4 which we already discussed back under `Routing`_:: $ N1SUBNET6_MAC=$(ovn-nbctl --bare --columns=mac find logical_router_port networks=\"fc11::1/64\") $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$N1SUBNET6_MAC' && ip6.src == fc11::5 && ip6.dst == fc22::7 && ip.ttl == 64 && icmp6.type == 8' ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "ap" && eth.src == {fa:16:3e:a9:4c:c7}, priority 50, uuid 6dcc418a next; 1. ls_in_port_sec_ip (northd.c:2390): inport == "ap" && eth.src == fa:16:3e:a9:4c:c7 && ip6.src == {fe80::f816:3eff:fea9:4cc7, fc11::5}, priority 90, uuid 604810ea next; 3. ls_in_pre_acl (northd.c:2646): ip, priority 100, uuid 46c089e6 reg0[0] = 1; next; 5. ls_in_pre_stateful (northd.c:2764): reg0[0] == 1, priority 100, uuid d1941634 ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 6. ls_in_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (inport == "ap" && ip6), priority 2002, uuid 7fdd607e next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:ef:2f:8b, priority 50, uuid e1d87fc5 outport = "ad952e"; output; egress(dp="n1", inport="ap", outport="ad952e") ---------------------------------------------- 1. ls_out_pre_acl (northd.c:2626): ip && outport == "ad952e", priority 110, uuid 88f68988 next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "ad952e", priority 50, uuid 5935755e output; /* output to "ad952e", type "patch" */ ingress(dp="r", inport="lrp-ad952e") ------------------------------------ 0. lr_in_admission (northd.c:4071): eth.dst == fa:16:3e:ef:2f:8b && inport == "lrp-ad952e", priority 50, uuid ddfeb712 next; 5. lr_in_ip_routing (northd.c:3782): ip6.dst == fc22::/64, priority 129, uuid cc2130ec ip.ttl--; xxreg0 = ip6.dst; xxreg1 = fc22::1; eth.src = fa:16:3e:06:de:ad; outport = "lrp-1a8162"; flags.loopback = 1; next; 6. lr_in_arp_resolve (northd.c:5122): outport == "lrp-1a8162" && xxreg0 == fc22::7, priority 100, uuid bcf75288 eth.dst = fa:16:3e:89:f2:36; next; 8. lr_in_arp_request (northd.c:5260): 1, priority 0, uuid 6dacdd82 output; egress(dp="r", inport="lrp-ad952e", outport="lrp-1a8162") --------------------------------------------------------- 3. lr_out_delivery (northd.c:5288): outport == "lrp-1a8162", priority 100, uuid 5260dfc5 output; /* output to "lrp-1a8162", type "patch" */ ingress(dp="n2", inport="1a8162") --------------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "1a8162", priority 50, uuid 10957d1b next; 3. ls_in_pre_acl (northd.c:2624): ip && inport == "1a8162", priority 110, uuid a27ebd00 next; 13. ls_in_l2_lkup (northd.c:3529): eth.dst == fa:16:3e:89:f2:36, priority 50, uuid dcafb3e9 outport = "cp"; output; egress(dp="n2", inport="1a8162", outport="cp") ---------------------------------------------- 1. ls_out_pre_acl (northd.c:2648): ip, priority 100, uuid cd9cfa74 reg0[0] = 1; next; 2. ls_out_pre_stateful (northd.c:2766): reg0[0] == 1, priority 100, uuid 9e8e22c5 ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 4. ls_out_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (outport == "cp" && ip6 && ip6.src == $as_ip6_0fc1b6cf_f925_49e6_8f00_6dd13beca9dc), priority 2002, uuid 12fc96f9 next; 7. ls_out_port_sec_ip (northd.c:2390): outport == "cp" && eth.dst == fa:16:3e:89:f2:36 && ip6.dst == {fe80::f816:3eff:fe89:f236, ff00::/8, fc22::7}, priority 90, uuid c622596a next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "cp" && eth.dst == {fa:16:3e:89:f2:36}, priority 50, uuid 0242cdc3 output; /* output to "cp", type "" */ ACLs ---- Let's explore how ACLs work in OpenStack and OVN. In OpenStack, ACL rules are part of "security groups", which are "default deny", that is, packets are not allowed by default and the rules added to security groups serve to allow different classes of packets. The default group (named "default") that is assigned to each of our VMs so far allows all traffic from our other VMs, which isn't very interesting for testing. So, let's create a new security group, which we'll name "custom", add rules to it that allow incoming SSH and ICMP traffic, and apply this security group to VM ``c``:: $ openstack security group create custom $ openstack security group rule create --dst-port 22 custom $ openstack security group rule create --protocol icmp custom $ openstack server remove security group c default $ openstack server add security group c custom Now we can do some experiments to test security groups. From the console on ``a`` or ``b``, it should now be possible to "ping" ``c`` or to SSH to it, but attempts to initiate connections on other ports should be blocked. (You can try to connect on another port with ``ssh -p PORT IP`` or ``nc IP PORT -vv``.) Connection attempts should time out rather than receive the "connection refused" or "connection reset" error that you would see between ``a`` and ``b``. It's also possible to test ACLs via ovn-trace, with one new wrinkle. ovn-trace can't simulate connection tracking state in the network, so by default it assumes that every packet represents an established connection. That's good enough for what we've been doing so far, but for checking properties of security groups we want to look at more detail. If you look back at the VM-to-VM traces we've done until now, you can see that they execute two ``ct_next`` actions: * The first of these is for the packet passing outward through the source VM's firewall. We can tell ovn-trace to treat the packet as starting a new connection or adding to an established connection by adding a ``--ct`` option: ``--ct new`` or ``--ct est``, respectively. The latter is the default and therefore what we've been using so far. We can also use ``--ct est,rpl``, which in addition to ``--ct est`` means that the connection was initiated by the destination VM rather than by the VM sending this packet. * The second is for the packet passing inward through the destination VM's firewall. For this one, it makes sense to tell ovn-trace that the packet is starting a new connection, with ``--ct new``, or that it is a packet sent in reply to a connection established by the destination VM, with ``--ct est,rpl``. ovn-trace uses the ``--ct`` options in order, so if we want to override the second ``ct_next`` behavior we have to specify two options. Another useful ovn-trace option for this testing is ``--minimal``, which reduces the amount of output. In this case we're really just interested in finding out whether the packet reaches the destination VM, that is, whether there's an eventual ``output`` action to ``c``, so ``--minimal`` works fine and the output is easier to read. Try a few traces. For example: First, obtain the mac address of logical router's IPv4 interface on ``n1``:: $ N1SUBNET4_MAC=$(ovn-nbctl --bare --columns=mac \ find logical_router_port networks=\"10.1.1.1/24\") * VM ``a`` initiates a new SSH connection to ``c``:: $ ovn-trace --ct new --ct new --minimal n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$N1SUBNET4_MAC' && ip4.src == 10.1.1.5 && ip4.dst == 10.1.2.7 && ip.ttl == 64 && tcp.dst == 22' ... ct_next(ct_state=new|trk) { ip.ttl--; eth.src = fa:16:3e:19:9f:46; eth.dst = fa:16:3e:89:f2:36; ct_next(ct_state=new|trk) { output("cp"); }; }; This succeeds, as you can see since there is an ``output`` action. * VM ``a`` initiates a new Telnet connection to ``c``:: $ ovn-trace --ct new --ct new --minimal n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$N1SUBNET4_MAC' && ip4.src == 10.1.1.5 && ip4.dst == 10.1.2.7 && ip.ttl == 64 && tcp.dst == 23' ct_next(ct_state=new|trk) { ip.ttl--; eth.src = fa:16:3e:19:9f:46; eth.dst = fa:16:3e:89:f2:36; ct_next(ct_state=new|trk); }; This fails, as you can see from the lack of an ``output`` action. * VM ``a`` replies to a packet that is part of a Telnet connection originally initiated by ``c``:: $ ovn-trace --ct est,rpl --ct est,rpl --minimal n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == '$N1SUBNET4_MAC' && ip4.src == 10.1.1.5 && ip4.dst == 10.1.2.7 && ip.ttl == 64 && tcp.dst == 23' ... ct_next(ct_state=est|rpl|trk) { ip.ttl--; eth.src = fa:16:3e:19:9f:46; eth.dst = fa:16:3e:89:f2:36; ct_next(ct_state=est|rpl|trk) { output("cp"); }; }; This succeeds, as you can see from the ``output`` action, since traffic received in reply to an outgoing connection is always allowed. DHCP ---- As a final demonstration of the OVN architecture, let's examine the DHCP implementation. Like switching, routing, and NAT, the OVN implementation of DHCP involves configuration in the NB DB and logical flows in the SB DB. Let's look at the DHCP support for ``a``'s port ``ap``. The port's Logical_Switch_Port record shows that ``ap`` has DHCPv4 options:: $ ovn-nbctl list logical_switch_port ap | abbrev _uuid : ef17e5 addresses : ["fa:16:3e:a9:4c:c7 10.1.1.5 fc11::5"] dhcpv4_options : 165974 dhcpv6_options : 26f7cd dynamic_addresses : [] enabled : true external_ids : {"neutron:port_name"=ap} name : "820c08" options : {} parent_name : [] port_security : ["fa:16:3e:a9:4c:c7 10.1.1.5 fc11::5"] tag : [] tag_request : [] type : "" up : true We can then list them either by UUID or, more easily, by port name:: $ ovn-nbctl list dhcp_options ap | abbrev _uuid : 165974 cidr : "10.1.1.0/24" external_ids : {subnet_id="5e67e7"} options : {lease_time="43200", mtu="1442", router="10.1.1.1", server_id="10.1.1.1", server_mac="fa:16:3e:bb:94:72"} These options show the basic DHCP configuration for the subnet. They do not include the IP address itself, which comes from the Logical_Switch_Port record. This allows a whole Neutron subnet to share a single DHCP_Options record. You can see this sharing in action, if you like, by listing the record for port ``bp``, which is on the same subnet as ``ap``, and see that it is the same record as before:: $ ovn-nbctl list dhcp_options bp | abbrev _uuid : 165974 cidr : "10.1.1.0/24" external_ids : {subnet_id="5e67e7"} options : {lease_time="43200", mtu="1442", router="10.1.1.1", server_id="10.1.1.1", server_mac="fa:16:3e:bb:94:72"} You can take another look at the southbound flow table if you like, but the best demonstration is to trace a DHCP packet. The following is a trace of a DHCP request inbound from ``ap``. The first part is just the usual travel through the firewall:: $ ovn-trace n1 'inport == "ap" && eth.src == '$AP_MAC' && eth.dst == ff:ff:ff:ff:ff:ff && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67 && ip.ttl == 1' ... ingress(dp="n1", inport="ap") ----------------------------- 0. ls_in_port_sec_l2 (northd.c:3234): inport == "ap" && eth.src == {fa:16:3e:a9:4c:c7}, priority 50, uuid 6dcc418a next; 1. ls_in_port_sec_ip (northd.c:2325): inport == "ap" && eth.src == fa:16:3e:a9:4c:c7 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67, priority 90, uuid e46bed6f next; 3. ls_in_pre_acl (northd.c:2646): ip, priority 100, uuid 46c089e6 reg0[0] = 1; next; 5. ls_in_pre_stateful (northd.c:2764): reg0[0] == 1, priority 100, uuid d1941634 ct_next; The next part is the new part. First, an ACL in table 6 allows a DHCP request to pass through. In table 11, the special ``put_dhcp_opts`` action replaces a DHCPDISCOVER or DHCPREQUEST packet by a reply. Table 12 flips the packet's source and destination and sends it back the way it came in:: 6. ls_in_acl (northd.c:2925): !ct.new && ct.est && !ct.rpl && ct_label.blocked == 0 && (inport == "ap" && ip4 && ip4.dst == {255.255.255.255, 10.1.1.0/24} && udp && udp.src == 68 && udp.dst == 67), priority 2002, uuid 9c90245d next; 11. ls_in_dhcp_options (northd.c:3409): inport == "ap" && eth.src == fa:16:3e:a9:4c:c7 && ip4.src == 0.0.0.0 && ip4.dst == 255.255.255.255 && udp.src == 68 && udp.dst == 67, priority 100, uuid 8d63f29c reg0[3] = put_dhcp_opts(offerip = 10.1.1.5, lease_time = 43200, mtu = 1442, netmask = 255.255.255.0, router = 10.1.1.1, server_id = 10.1.1.1); /* We assume that this packet is DHCPDISCOVER or DHCPREQUEST. */ next; 12. ls_in_dhcp_response (northd.c:3438): inport == "ap" && eth.src == fa:16:3e:a9:4c:c7 && ip4 && udp.src == 68 && udp.dst == 67 && reg0[3], priority 100, uuid 995eeaa9 eth.dst = eth.src; eth.src = fa:16:3e:bb:94:72; ip4.dst = 10.1.1.5; ip4.src = 10.1.1.1; udp.src = 67; udp.dst = 68; outport = inport; flags.loopback = 1; output; Then the last part is just traveling back through the firewall to VM ``a``:: egress(dp="n1", inport="ap", outport="ap") ------------------------------------------ 1. ls_out_pre_acl (northd.c:2648): ip, priority 100, uuid 3752b746 reg0[0] = 1; next; 2. ls_out_pre_stateful (northd.c:2766): reg0[0] == 1, priority 100, uuid 0c066ea1 ct_next; ct_next(ct_state=est|trk /* default (use --ct to customize) */) --------------------------------------------------------------- 4. ls_out_acl (northd.c:3008): outport == "ap" && eth.src == fa:16:3e:bb:94:72 && ip4.src == 10.1.1.1 && udp && udp.src == 67 && udp.dst == 68, priority 34000, uuid 0b383e77 ct_commit; next; 7. ls_out_port_sec_ip (northd.c:2364): outport == "ap" && eth.dst == fa:16:3e:a9:4c:c7 && ip4.dst == {255.255.255.255, 224.0.0.0/4, 10.1.1.5}, priority 90, uuid 7b8cbcd5 next; 8. ls_out_port_sec_l2 (northd.c:3654): outport == "ap" && eth.dst == {fa:16:3e:a9:4c:c7}, priority 50, uuid b874ece8 output; /* output to "ap", type "" */ Further Directions ------------------ We've looked at a fair bit of how OVN works and how it interacts with OpenStack. If you still have some interest, then you might want to explore some of these directions: * Adding more than one hypervisor ("compute node", in OpenStack parlance). OVN connects compute nodes by tunneling packets with the Geneve protocol. OVN scales to 1000 compute nodes or more, but two compute nodes demonstrate the principle. All of the tools and techniques we demonstrated also work with multiple compute nodes. * Container support. OVN supports seamlessly connecting VMs to containers, whether the containers are hosted on "bare metal" or nested inside VMs. OpenStack support for containers, however, is still evolving, and too difficult to incorporate into the tutorial at this point. * Other kinds of gateways. In addition to floating IPs with NAT, OVN supports directly attaching VMs to a physical network and connecting logical switches to VTEP hardware. ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-ovsdb-relay.rst000066400000000000000000000233601504532661100255710ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========================================== Running OVN Southbound DB with OVSDB Relay ========================================== This tutorial shows how to run and configure OVN database daemons to offload ``ovn-controller``-related read workload from OVN Southbound database cluster. This is useful in large-scale deployments with a big number of ovn-controllers. --------------------- Design considerations --------------------- The design assumes there is a working OVSDB RAFT cluster. Configure this cluster to accept connections from ``ovn-northd``, ``ovn-ic`` and ``ovsdb-server``-relay processes. All these processes require direct access to OVN Southbound DB cluster. Other clients (``ovn-controller`` and ``ovn-controller-vtep``) connect to relay ovsdb servers. These relay servers maintain connections to ``ovn-controllers``, send out database updates and forward DB updates to database cluster. .. note:: In this doc the set of OVSDB Relay servers, which has same parameters: upstream servers, remotes and clients, will be called a *group*. OVSDB Relay supports creating multi-tier deployment, where one set (group) of relay ovsdb-servers is connected to ovsdb raft cluster, the other set of relay ovsdb-servers can be connected to the first set of relays and this can be repeated multiple times horizontally (multiple groups connected to one group) and/or vertically (multiple groups connected one-by-one in a chain). OVN Southbound OVSDB cluster must be configured with at least one remote, which allows OVSDB Relay servers to connnect to it. This remote must not have configured RBAC rules. RBAC rules can be configured to be checked on the OVSDB Relay servers, which are used to connect to ovn-controller and ovn-controller-vtep. ------------------ Deployment options ------------------ Three variants of deployment will be covered in this tutorial: #. :ref:`One-group deployment`: one OVSDB Relays group connected to OVSDB cluster. #. :ref:`Multi-group deployment`: multiple groups of OVSDB Relays connected to OVSDB cluster. #. :ref:`Two-tier multi-group deployment`: one group of OVSDB Relays connected to OVSDB cluster and another multiple OVSDB Relay groups connected to the first group. .. _one_group: ~~~~~~~~~~~~~~~~~~~~ One-group deployment ~~~~~~~~~~~~~~~~~~~~ .. image:: ../tutorials/images/ovsdb-relay-1.png :width: 80% :alt: OVSDB Relay one-group deployment Example commands to run this configuration: Start SB cluster and ovn-northd: :: # start OVN_Southbound cluster /usr/share/ovn/scripts/ovn-ctl start_sb_ovsdb \ --db-sb-cluster-local-addr=127.0.0.1 \ -- --remote=ptcp:16642 # start ovn-northd and connect directly to cluster /usr/share/ovn/scripts/ovn-ctl start_northd \ --ovn-manage-ovsdb=no \ --ovn-northd-nb-db=... \ --ovn-northd-sb-db=tcp:127.0.0.1:16642 To use **TCP** between ovn-controller and OVSDB Relay: :: # start OVSDB Southbound Relay and connect to cluster /usr/share/ovn/scripts/ovn-ctl start_sb_relay_ovsdb \ --db-sb-relay-remote=tcp:127.0.0.1:16642 \ -- --remote=ptcp:6642 # start ovn-controller and connect to OVSDB Relay ovs-vsctl set external_ids:ovn-remote="tcp:127.0.0.1:6642" /usr/share/ovn/scripts/ovn-ctl start_controller To use **SSL/TLS** between ovn-controller and OVSDB Relay: :: # start OVSDB Southbound Relay and connect to cluster /usr/share/ovn/scripts/ovn-ctl start_sb_relay_ovsdb \ --db-sb-relay-remote=tcp:127.0.0.1:16642 \ --ovn-sb-relay-db-ssl-key=/path/to/ovsdb/relay/ssl-key.pem \ --ovn-sb-relay-db-ssl-cert=/path/to/ovsdb/relay/ssl-cert.pem \ --ovn-sb-relay-db-ssl-ca-cert=/path/to/ovsdb/relay/ssl-ca-cert.pem \ -- --remote=pssl:6642 # start ovn-controller and connect to OVSDB Relay ovs-vsctl set external_ids:ovn-remote="ssl:127.0.0.1:6642" ovs-vsctl set-ssl <...> /usr/share/ovn/scripts/ovn-ctl start_controller To use **SSL/TLS with RBAC** between ovn-controller and OVSDB Relay: :: # configure RBAC. create RBAC-enabled connection in SB DB: ovn-sbctl set-connection role=ovn-controller pssl:6642 # start OVSDB Southbound Relay and connect to cluster /usr/share/ovn/scripts/ovn-ctl start_sb_relay_ovsdb \ --db-sb-relay-remote=tcp:127.0.0.1:16642 \ --ovn-sb-relay-db-ssl-key=/path/to/ovsdb/relay/ssl-key.pem \ --ovn-sb-relay-db-ssl-cert=/path/to/ovsdb/relay/ssl-cert.pem \ --ovn-sb-relay-db-ssl-ca-cert=/path/to/ovsdb/relay/ssl-ca-cert.pem # start ovn-controller and connect to OVSDB Relay ovs-vsctl set external_ids:ovn-remote="ssl:127.0.0.1:6642" /usr/share/ovn/scripts/ovn-ctl start_controller This is the most simple deployment, which can be used even in small-scale deployments to remove ovn-controller-related load from OVSDB cluster. All cluster leader elections will not be noticed by ovn-controllers, no reconnections and full DB re-sync, which can trigger avalanche-like load on OVSDB cluster will not take place. RAFT cluster will maintain only connections to ovn-northd, ovsdb-relay servers and, optionally, ovn-ic. .. note:: Check :ref:`this documentation` for more details about RBAC configuration. .. _multi_group: ~~~~~~~~~~~~~~~~~~~~~~ Multi-group deployment ~~~~~~~~~~~~~~~~~~~~~~ .. image:: ../tutorials/images/ovsdb-relay-2.png :width: 80% :alt: OVSDB Relay multi-group deployment The difference between this deployment option and "one-group" is that it is possible to dedicate different groups of OVSDB Relays to serve different sets of ovn-controllers. This deployment scenario can be used when it is needed to bring OVSDB Relays closer to ovn-controllers (POD), split the Relay servers by some tag or split large OVSDB Relay group by multiple small groups. OVSDB cluster and Relays configuration is similar to the first scenario. The difference is in ovn-controller ``remote`` configuration: for ovn-controller from different groups appropriate ``ovn-remote`` external IDs should be configured: Group 1: :: ovs-vsctl set open . external_ids:ovn-remote=ssl:10.0.0.10:6642,ssl:10.0.0.11:6642 Group 2: :: ovs-vsctl set open . external_ids:ovn-remote=ssl:10.0.0.20:6642,ssl:10.0.0.21:6642 And so on. It is adviced to configure at least two OVSDB Relay servers for ovn-controller if high-avalability is important. .. _two_tier_multi_group: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Two-tier multi-group deployment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. image:: ../tutorials/images/ovsdb-relay-3.png :width: 80% :alt: OVSDB Relay two-tier multi-group deployment This deployment scenario can be useful if the count of OVSDB Relay groups from previous (multi-group) scenario becomes an issue for the OVSDB cluster and brings unwanted load on it. Deploy an intermediate group of OVSDB Relay servers to have just N connections on the cluster ovsdb-servers (where N is a number of Relay servers in this group), while other OVSDB Relay groups connect to this "intermediate" group. This extra level of OVSDB Relay servers gives more abilities of scale by the cost of the increased latency of writes and DB updates. Configuration of OVSDB cluster is similar to the first scenario. Commands to start "intermediate" OVSDB Relay: :: /usr/share/ovn/scripts/ovn-ctl start_sb_relay_ovsdb \ --db-sb-relay-remote=tcp:127.0.0.1:16642 \ --db-sb-relay-use-remote-in-db=no \ --ovn-sb-relay-db-ssl-key=/path/to/ovsdb/relay/ssl-key.pem \ --ovn-sb-relay-db-ssl-cert=/path/to/ovsdb/relay/ssl-cert.pem \ --ovn-sb-relay-db-ssl-ca-cert=/path/to/ovsdb/relay/ssl-ca-cert.pem \ -- --remote=pssl:26642 .. note:: OVSDB Relay "intermediate" servers should not use listening RBAC-enabled remote. If RBAC is used, it should be configured on the OVSDB Relay servers to which ovn-controller and ovn-controller-vtep are connected. Next, start "last-level" OVSDB Relay servers, to which ovn-controllers would be connected. To use **SSL/TLS with RBAC** between ovn-controller and OVSDB Relay: :: # configure RBAC. create RBAC-enabled connection in SB DB: ovn-sbctl set-connection role=ovn-controller pssl:6642 # start OVSDB Southbound Relay and connect to intermediate OVSDB Relay group # start as many OVSDB Relays as needed. /usr/share/ovn/scripts/ovn-ctl start_sb_relay_ovsdb \ --db-sb-relay-remote=tcp:127.0.0.1:26642 \ --ovn-sb-relay-db-ssl-key=/path/to/ovsdb/relay/ssl-key.pem \ --ovn-sb-relay-db-ssl-cert=/path/to/ovsdb/relay/ssl-cert.pem \ --ovn-sb-relay-db-ssl-ca-cert=/path/to/ovsdb/relay/ssl-ca-cert.pem # start ovn-controller and connect to appropriate OVSDB Relay servers ovs-vsctl set external_ids:ovn-remote="ssl:127.0.0.1:6642" /usr/share/ovn/scripts/ovn-ctl start_controller .. warning:: OVSDB Relay feature was added in openvswitch 2.16. Ensure your deployment uses appropriate openvswitch version to utilize this feature. .. note:: More details about OVSDB Relay can be found in `Open vSwitch OVSDB Relay documentation `_. ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-rbac.rst000066400000000000000000000134361504532661100242540ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. .. _ovn_rbac: ============================================= OVN Role-Based Access Control (RBAC) Tutorial ============================================= This document provides a step-by-step guide for setting up role-based access control (RBAC) in OVN. In OVN, hypervisors (chassis) read and write the southbound database to do configuration. Without restricting hypervisor's access to the southbound database, a compromised hypervisor might disrupt the entire OVN deployment by corrupting the database. RBAC ensures that each hypervisor can only modify its own data and thus improves the security of OVN. More details about the RBAC design can be found in ``ovn-architecture``\(7) manpage. This document assumes OVN is installed in your system and runs normally. .. _gen-certs-keys: Generating Certificates and Keys -------------------------------- In the OVN RBAC deployment, ovn-controller connects to the southbound database via SSL/TLS connection. The southbound database uses CA-signed certificate to authenticate ovn-controller. Suppose there are three machines in your deployment. `machine_1` runs `chassis_1` and has IP address `machine_1-ip`. `machine_2` runs `chassis_2` and has IP address `machine_2-ip`. `machine_3` hosts southbound database and has IP address `machine_3-ip`. `machine_3` also hosts public key infrastructure (PKI). 1. Initiate PKI. In `machine_3`:: $ ovs-pki init 2. Generate southbound database's certificate request. Sign the certificate request with the CA key. In `machine_3`:: $ ovs-pki req -u sbdb $ ovs-pki sign sbdb switch 3. Generate chassis certificate requests. Copy the certificate requests to `machine_3`. In `machine_1`:: $ ovs-pki req -u chassis_1 $ scp chassis_1-req.pem \ machine_3@machine_3-ip:/path/to/chassis_1-req.pem In `machine_2`:: $ ovs-pki req -u chassis_2 $ scp chassis_2-req.pem \ machine_3@machine_3-ip:/path/to/chassis_2-req.pem .. note:: chassis_1 must be the same string as ``external_ids:system-id`` in the Open_vSwitch table (the chassis name) of machine_1. Same applies for chassis_2. 4. Sign the chassis certificate requests with the CA key. Copy `chassis_1`'s signed certificate and the CA certificate to `machine_1`. Copy `chassis_2`'s signed certificate and the CA certificate to `machine_2`. In `machine_3`:: $ ovs-pki sign chassis_1 switch $ ovs-pki sign chassis_2 switch $ scp chassis_1-cert.pem \ machine_1@machine_1-ip:/path/to/chassis_1-cert.pem $ scp /var/lib/openvswitch/pki/switchca/cacert.pem \ machine_1@machine_1-ip:/path/to/cacert.pem $ scp chassis_2-cert.pem \ machine_2@machine_2-ip:/path/to/chassis_2-cert.pem $ scp /var/lib/openvswitch/pki/switchca/cacert.pem \ machine_2@machine_2-ip:/path/to/cacert.pem Configuring RBAC ---------------- 1. Set certificate, private key, and CA certificate for the southbound database. Configure the southbound database to listen on SSL/TLS connection and enforce role-based access control. In `machine_3`:: $ ovn-sbctl set-ssl /path/to/sbdb-privkey.pem \ /path/to/sbdb-cert.pem /path/to/cacert.pem $ ovn-sbctl set-connection role=ovn-controller pssl:6642 2. Set certificate, private key, and CA certificate for `chassis_1` and `chassis_2`. Configure `chassis_1` and `chassis_2` to connect southbound database via SSL/TLS. In `machine_1`:: $ ovs-vsctl set-ssl /path/to/chassis_1-privkey.pem \ /path/to/chassis_1-cert.pem /path/to/cacert.pem $ ovs-vsctl set open_vswitch . \ external_ids:ovn-remote=ssl:machine_3-ip:6642 In `machine_2`:: $ ovs-vsctl set-ssl /path/to/chassis_2-privkey.pem \ /path/to/chassis_2-cert.pem /path/to/cacert.pem $ ovs-vsctl set open_vswitch . \ external_ids:ovn-remote=ssl:machine_3-ip:6642 The OVN central control daemon and RBAC ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The OVN central control daemon (`ovn-northd`) needs full write access to the southbound database. When you have one machine hosting the central components, `ovn-northd` can talk to the databases through a local unix socket, bypassing the `ovn-controller` RBAC configured for the listener at port '6642'. However, if you want to deploy multiple machines for hosting the central components, `ovn-northd` will require a remote connection to all of them. 1. Configure the southbound database with a second SSL/TLS listener on a separate port without RBAC enabled for use by `ovn-northd`. In `machine_3`:: $ ovn-sbctl -- --id=@conn_uuid create Connection \ target="pssl\:16642" \ -- add SB_Global . connections=@conn_uuid .. note:: Care should be taken to restrict access to the above mentioned port so that only trusted machines can connect to it. ovn-25.09.0~git20250813.23884f5/Documentation/tutorials/ovn-sandbox.rst000066400000000000000000000156211504532661100250010ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. =========== OVN Sandbox =========== This tutorial shows you how to explore features using ``ovn-sandbox`` as a simulated test environment. It's assumed that you have an understanding of OVS before going through this tutorial. Detail about OVN is covered in ovn-architecture_, but this tutorial lets you quickly see it in action. Getting Started --------------- ``ovn-sandbox`` is derived from the Open vSwitch ``ovs-sandbox`` utility. For some general information about it, see the "Getting Started" section of `ovs-advanced`_ in the Open vSwitch documentation. ``ovn-sandbox`` in the OVN repo includes OVN support by default. To start it, you would simply need to run:: $ make sandbox Running the sandbox does the following steps to the environment: 1. Creates the ``OVN_Northbound`` and ``OVN_Southbound`` databases as described in `ovn-nb(5)`_ and `ovn-sb(5)`_. 2. Creates a backup server for ``OVN_Southbond`` database. Sandbox launch screen provides the instructions on accessing the backup database. However access to the backup server is not required to go through the tutorial. 3. Creates the ``hardware_vtep`` database as described in `vtep(5)`_. 4. Runs the `ovn-northd(8)`_, `ovn-controller(8)`_, and `ovn-controller-vtep(8)`_ daemons. 5. Makes OVN and VTEP utilities available for use in the environment, including `vtep-ctl(8)`_, `ovn-nbctl(8)`_, and `ovn-sbctl(8)`_. Using GDB --------- GDB support is not required to go through the tutorial. See the "Using GDB" section of `ovs-advanced`_ in the Open vSwitch documentation for more info. Additional flags exist for launching the debugger for the OVN programs:: --gdb-ovn-northd --gdb-ovn-controller --gdb-ovn-controller-vtep Creating OVN Resources ---------------------- Once you have ``ovn-sandbox`` running, you can start using OVN utilities to create resources. As an example, we will create an environment that has two logical switches connected by a logical router. Create the first logical switch with one port:: $ ovn-nbctl ls-add sw0 $ ovn-nbctl lsp-add sw0 sw0-port1 $ ovn-nbctl lsp-set-addresses sw0-port1 "50:54:00:00:00:01 192.168.0.2" Create the second logical switch with one port:: $ ovn-nbctl ls-add sw1 $ ovn-nbctl lsp-add sw1 sw1-port1 $ ovn-nbctl lsp-set-addresses sw1-port1 "50:54:00:00:00:03 11.0.0.2" Create the logical router and attach both logical switches:: $ ovn-nbctl lr-add lr0 $ ovn-nbctl lrp-add lr0 lrp0 00:00:00:00:ff:01 192.168.0.1/24 $ ovn-nbctl lsp-add sw0 lrp0-attachment $ ovn-nbctl lsp-set-type lrp0-attachment router $ ovn-nbctl lsp-set-addresses lrp0-attachment 00:00:00:00:ff:01 $ ovn-nbctl lsp-set-options lrp0-attachment router-port=lrp0 $ ovn-nbctl lrp-add lr0 lrp1 00:00:00:00:ff:02 11.0.0.1/24 $ ovn-nbctl lsp-add sw1 lrp1-attachment $ ovn-nbctl lsp-set-type lrp1-attachment router $ ovn-nbctl lsp-set-addresses lrp1-attachment 00:00:00:00:ff:02 $ ovn-nbctl lsp-set-options lrp1-attachment router-port=lrp1 View a summary of OVN's current logical configuration:: $ ovn-nbctl show switch 1396cf55-d176-4082-9a55-1c06cef626e4 (sw1) port lrp1-attachment addresses: ["00:00:00:00:ff:02"] port sw1-port1 addresses: ["50:54:00:00:00:03 11.0.0.2"] switch 2c9d6d03-09fc-4e32-8da6-305f129b0d53 (sw0) port lrp0-attachment addresses: ["00:00:00:00:ff:01"] port sw0-port1 addresses: ["50:54:00:00:00:01 192.168.0.2"] router f8377e8c-f75e-4fc8-8751-f3ea03c6dd98 (lr0) port lrp0 mac: "00:00:00:00:ff:01" networks: ["192.168.0.1/24"] port lrp1 mac: "00:00:00:00:ff:02" networks: ["11.0.0.1/24"] The ``tutorial`` directory of the OVN source tree includes a script that runs all of the commands for you:: $ ./ovn-setup.sh Using ovn-trace --------------- Once you have configured resources in OVN, try using ``ovn-trace`` to see how OVN would process a sample packet through its logical pipeline. For example, we can trace an IP packet from ``sw0-port1`` to ``sw1-port1``. The ``--minimal`` output shows each visible action performed on the packet, which includes: #. The logical router will decrement the IP TTL field. #. The logical router will change the source and destination MAC addresses to reflect the next hop. #. The packet will be output to ``sw1-port1``. :: $ ovn-trace --minimal sw0 'inport == "sw0-port1" \ > && eth.src == 50:54:00:00:00:01 && ip4.src == 192.168.0.2 \ > && eth.dst == 00:00:00:00:ff:01 && ip4.dst == 11.0.0.2 \ > && ip.ttl == 64' # ip,reg14=0x1,vlan_tci=0x0000,dl_src=50:54:00:00:00:01,dl_dst=00:00:00:00:ff:01,nw_src=192.168.0.2,nw_dst=11.0.0.2,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=64 ip.ttl--; eth.src = 00:00:00:00:ff:02; eth.dst = 50:54:00:00:00:03; output("sw1-port1"); The ``ovn-trace`` utility can also provide much more detail on how the packet would be processed through OVN's logical pipeline, as well as correlate that to OpenFlow flows programmed by ``ovn-controller``. See the `ovn-trace(8)`_ man page for more detail. .. _ovn-architecture: http://www.ovn.org/support/dist-docs/ovn-architecture.7.html .. _ovn-nb(5): http://www.ovn.org/support/dist-docs/ovn-nb.5.html .. _ovn-sb(5): http://www.ovn.org/support/dist-docs/ovn-sb.5.html .. _vtep(5): http://openvswitch.org/support/dist-docs/vtep.5.html .. _ovn-northd(8): http://www.ovn.org/support/dist-docs/ovn-northd.8.html .. _ovn-controller(8): http://www.ovn.org/support/dist-docs/ovn-controller.8.html .. _ovn-controller-vtep(8): http://www.ovn.org/support/dist-docs/ovn-controller-vtep.8.html .. _vtep-ctl(8): http://openvswitch.org/support/dist-docs/vtep-ctl.8.html .. _ovn-nbctl(8): http://www.ovn.org/support/dist-docs/ovn-nbctl.8.html .. _ovn-sbctl(8): http://www.ovn.org/support/dist-docs/ovn-sbctl.8.html .. _ovn-trace(8): http://www.ovn.org/support/dist-docs/ovn-trace.8.html .. _ovs-advanced: https://github.com/openvswitch/ovs/blob/main/Documentation/tutorials/ovs-advanced.rst ovn-25.09.0~git20250813.23884f5/LICENSE000066400000000000000000000250171504532661100161570ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS Copyright The Open vSwitch Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ovn-25.09.0~git20250813.23884f5/MAINTAINERS.rst000066400000000000000000000046541504532661100174620ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ========== Committers ========== OVN committers are the people who have been granted access to push changes to the OVN git repository. The responsibilities of an OVN committer are documented here: |responsibilities|. The process for adding or removing committers is documented here: |grant-revocation|. This is the current list of active OVN committers: .. list-table:: OVN Maintainers :header-rows: 1 * - Name - Email * - AleÅ¡ Musil - amusil@redhat.com * - Dumitru Ceara - dceara@redhat.com * - Han Zhou - hzhou@ovn.org * - Leonid Ryzhyk - lryzhyk@vmware.com * - Mark Michelson - mmichels@redhat.com * - Numan Siddique - nusiddiq@redhat.com\, numans@ovn.org The project also maintains a list of Emeritus Committers (or Maintainers). More information about Emeritus Committers can be found here: |emeritus-status|. .. list-table:: OVN Emeritus Maintainers :header-rows: 1 * - Name - Email * - Ben Pfaff - blp@ovn.org * - Gurucharan Shetty - guru@ovn.org * - Justin Pettit - jpettit@ovn.org * - Russell Bryant - russell@ovn.org .. Cut here for the Documentation/internals/maintainers.rst .. |responsibilities| replace:: `Expectations for Developers with OVN Repo Access `__ .. |grant-revocation| replace:: `OVN Committer Grant/Revocation Policy `__ .. |emeritus-status| replace:: `Emeritus Status for OVN Committers `__ ovn-25.09.0~git20250813.23884f5/Makefile.am000066400000000000000000000411231504532661100172020ustar00rootroot00000000000000# Copyright (C) 2007-2017 Nicira, Inc. # # Copying and distribution of this file, with or without modification, # are permitted in any medium without royalty provided the copyright # notice and this notice are preserved. This file is offered as-is, # without warranty of any kind. AUTOMAKE_OPTIONS = foreign subdir-objects ACLOCAL_AMFLAGS = -I m4 #SUBDIRS = ovs OVS_SRCDIR=@ovs_srcdir@ OVS_BUILDDIR=@ovs_builddir@ OVS_LIBDIR=@ovs_libdir@ OVSDB_LIBDIR=@ovsdb_libdir@ OVS_MANDIR=@ovs_mandir@ AM_CPPFLAGS = $(SSL_CFLAGS) AM_LDFLAGS = $(SSL_LDFLAGS) AM_LDFLAGS += $(OVS_LDFLAGS) AM_CPPFLAGS += -I $(top_srcdir)/include if WIN32 AM_CPPFLAGS += $(PTHREAD_INCLUDES) AM_CPPFLAGS += $(MSVC_CFLAGS) AM_LDFLAGS += $(PTHREAD_LDFLAGS) AM_LDFLAGS += $(MSVC64_LDFLAGS) PLATFORM = $(MSVC_PLATFORM) endif AM_CPPFLAGS += -I $(top_srcdir)/include AM_CPPFLAGS += -I $(top_srcdir)/ovn AM_CPPFLAGS += -I $(top_builddir)/include AM_CPPFLAGS += -I $(top_srcdir)/lib AM_CPPFLAGS += -I $(top_builddir)/lib AM_CPPFLAGS += -I $(OVS_SRCDIR)/include AM_CPPFLAGS += -I $(OVS_BUILDDIR)/include AM_CPPFLAGS += -I $(OVS_SRCDIR)/lib AM_CPPFLAGS += -I $(OVS_BUILDDIR)/lib AM_CPPFLAGS += -I $(OVS_SRCDIR) AM_CPPFLAGS += -I $(OVS_BUILDDIR) AM_CPPFLAGS += $(SSL_INCLUDES) AM_CFLAGS = -Wstrict-prototypes AM_CFLAGS += $(WARNING_FLAGS) AM_CFLAGS += $(OVS_CFLAGS) AM_DISTCHECK_CONFIGURE_FLAGS = --with-ovs-source=$(PWD)/ovs if NDEBUG AM_CPPFLAGS += -DNDEBUG AM_CFLAGS += -fomit-frame-pointer endif AM_CTAGSFLAGS = $(OVS_CTAGS_IDENTIFIERS_LIST) if WIN32 psep=";" else psep=":" endif # PYTHONDONTWRITEBYTECODE=yes keeps Python from creating .pyc and .pyo # files. Creating .py[co] works OK for any given version of Open # vSwitch, but it causes trouble if you switch from a version with # foo/__init__.py into an (older) version with plain foo.py, since # foo/__init__.pyc will cause Python to ignore foo.py. run_python = \ PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH \ PYTHONDONTWRITEBYTECODE=yes $(PYTHON3) ALL_LOCAL = BUILT_SOURCES = CLEANFILES = CLEAN_LOCAL = DISTCLEANFILES = PYCOV_CLEAN_FILES = build-aux/check-structs,cover EXTRA_DIST = \ AUTHORS.rst \ CONTRIBUTING.rst \ LICENSE \ MAINTAINERS.rst \ README.rst \ NOTICE \ .cirrus.yml \ .ci/ci.sh \ .ci/linux-build.sh \ .ci/linux-util.sh \ .ci/osx-build.sh \ .ci/osx-prepare.sh \ .ci/ovn-kubernetes/Dockerfile \ .ci/ovn-kubernetes/prepare.sh \ .ci/ovn-kubernetes/custom.patch \ .github/workflows/containers.yml \ .github/workflows/test.yml \ .github/workflows/ovn-kubernetes.yml \ .github/workflows/ovn-fake-multinode-tests.yml \ .readthedocs.yaml \ boot.sh \ $(MAN_FRAGMENTS) \ $(MAN_ROOTS) \ Vagrantfile \ Vagrantfile-FreeBSD \ .mailmap \ TODO.rst \ TODO_SPLIT.rst \ ovn-architecture.7.xml \ ovn-nb.ovsschema \ ovn-nb.xml \ ovn-sb.ovsschema \ ovn-sb.xml \ ovn-ic-nb.ovsschema \ ovn-ic-nb.xml \ ovn-ic-sb.ovsschema \ ovn-ic-sb.xml bin_PROGRAMS = sbin_PROGRAMS = bin_SCRIPTS = DIST_HOOKS = dist_man_MANS = dist_pkgdata_DATA = dist_pkgdata_SCRIPTS = dist_sbin_SCRIPTS = dist_scripts_SCRIPTS = dist_scripts_DATA = EXTRA_PROGRAMS = INSTALL_DATA_LOCAL = UNINSTALL_LOCAL = man_MANS = MAN_FRAGMENTS = MAN_ROOTS = noinst_DATA = noinst_HEADERS = lib_LTLIBRARIES = noinst_LTLIBRARIES = noinst_man_MANS = noinst_PROGRAMS = noinst_SCRIPTS = OVSIDL_BUILT = pkgdata_DATA = sbin_SCRIPTS = scripts_SCRIPTS = completion_SCRIPTS = scripts_DATA = SUFFIXES = check_DATA = check_SCRIPTS = pkgconfig_DATA = FLAKE8_PYFILES = if ENABLE_SPARSE_BY_DEFAULT C ?= 1 endif scriptsdir = $(pkgdatadir)/scripts completiondir = $(sysconfdir)/bash_completion.d pkgconfigdir = $(libdir)/pkgconfig # This ensures that files added to EXTRA_DIST are always distributed, # even if they are inside an Automake if...endif conditional block that is # disabled by some particular "configure" run. For more information, see: # http://article.gmane.org/gmane.comp.sysutils.automake.general/10891 noinst_HEADERS += $(EXTRA_DIST) ro_c = echo '/* -*- mode: c; buffer-read-only: t -*- */' ro_shell = printf '\043 Generated automatically -- do not modify! -*- buffer-read-only: t -*-\n' submodules = $(shell grep 'path =' $(srcdir)/.gitmodules | sed -E 's/[\t ]*path =\s*(.*)/\1/g' | xargs) SUFFIXES += .in .in: $(AM_V_GEN)PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON3) $(srcdir)/build-aux/soexpand.py -I$(srcdir) -I$(OVS_SRCDIR) < $< | \ $(PYTHON3) $(srcdir)/build-aux/dpdkstrip.py $(DPDKSTRIP_FLAGS) | \ sed \ -e 's,[@]PKIDIR[@],$(PKIDIR),g' \ -e 's,[@]LOGDIR[@],$(LOGDIR),g' \ -e 's,[@]DBDIR[@],$(DBDIR),g' \ -e 's,[@]PYTHON3[@],$(PYTHON3),g' \ -e 's,[@]OVN_RUNDIR[@],$(OVN_RUNDIR),g' \ -e 's,[@]OVSBUILDDIR[@],$(OVSBUILDDIR),g' \ -e 's,[@]VERSION[@],$(VERSION),g' \ -e 's,[@]OVSVERSION[@],$(OVSVERSION),g' \ -e 's,[@]localstatedir[@],$(localstatedir),g' \ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \ -e 's,[@]sysconfdir[@],$(sysconfdir),g' \ -e 's,[@]bindir[@],$(bindir),g' \ -e 's,[@]sbindir[@],$(sbindir),g' \ -e 's,[@]abs_builddir[@],$(abs_builddir),g' \ -e 's,[@]abs_top_srcdir[@],$(abs_top_srcdir),g' \ > $@.tmp @if head -n 1 $@.tmp | grep '#!' > /dev/null; then \ chmod +x $@.tmp; \ fi $(AM_V_at) mv $@.tmp $@ SUFFIXES += .xml %: %.xml $(AM_V_GEN)$(run_python) $(srcdir)/build-aux/xml2nroff $< > $@.tmp \ -I $(srcdir) \ -I $(OVS_MANDIR) \ --version=$(VERSION) \ PKIDIR='$(PKIDIR)' \ LOGDIR='$(LOGDIR)' \ DBDIR='$(DBDIR)' \ PYTHON3='$(PYTHON3)' \ RUNDIR='$(RUNDIR)' \ OVN_RUNDIR='$(OVN_RUNDIR)' \ VERSION='$(VERSION)' \ localstatedir='$(localstatedir)' \ pkgdatadir='$(pkgdatadir)' \ sysconfdir='$(sysconfdir)' \ bindir='$(bindir)' \ sbindir='$(sbindir)' $(AM_v_at)mv $@.tmp $@ clean-pycov: cd $(srcdir) && rm -f $(PYCOV_CLEAN_FILES) CLEAN_LOCAL += clean-pycov .PHONY: clean-pycov # If we're checked out from a Git repository, make sure that every # file that is in Git is distributed. ALL_LOCAL += dist-hook-git dist-hook-git: distfiles @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1; then \ (cd $(srcdir) && git ls-files) | grep -v '\.gitignore$$' | \ grep -v '\.gitattributes$$' | \ grep -v '\.gitmodules$$' | \ grep -v "$(submodules)" | \ LC_ALL=C sort -u > all-gitfiles; \ LC_ALL=C comm -1 -3 distfiles all-gitfiles > missing-distfiles; \ if test -s missing-distfiles; then \ echo "The following files are in git but not the distribution:"; \ cat missing-distfiles; \ exit 1; \ fi; \ if LC_ALL=C grep '\.gitignore$$' distfiles; then \ echo "See above for list of files that are distributed but"; \ echo "should not be."; \ exit 1; \ fi \ fi CLEANFILES += distfiles all-gitfiles missing-distfiles # The following is based on commands for the Automake "distdir" target. distfiles: Makefile @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t" | \ LC_ALL=C sort -u > $@ CLEANFILES += distfiles .PHONY: dist-hook-git # Check that every .c file includes . ALL_LOCAL += config-h-check config-h-check: @cd $(srcdir); \ if test -e .git && (git --version) >/dev/null 2>&1 && \ git --no-pager grep -L '#include ' `git ls-files | grep -v $(submodules) | grep '\.c$$' | \ grep -vE '^python'`; \ then \ echo "See above for list of violations of the rule that"; \ echo "every C source file must #include ."; \ exit 1; \ fi .PHONY: config-h-check # Check for printf() type modifiers that MSVC doesn't support. ALL_LOCAL += printf-check printf-check: @cd $(srcdir); \ if test -e .git && (git --version) >/dev/null 2>&1 && \ git --no-pager grep -n -E -e '%[-+ #0-9.*]*([ztj]|hh)' --and --not -e 'ovs_scan' `git ls-files | grep -v $(submodules) | grep '\.[ch]$$'`; \ then \ echo "See above for list of violations of the rule that"; \ echo "'z', 't', 'j', 'hh' printf() type modifiers are"; \ echo "forbidden. See coding-style.rst for replacements."; \ exit 1; \ fi .PHONY: printf-check # Check that certain data structures are always declared "static". ALL_LOCAL += static-check static-check: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ git --no-pager grep -n -E '^[ ]+(struct vlog_rate_limit|pthread_once_t|struct ovsthread_once).*=' $(srcdir); \ then \ echo "See above for list of violations of the rule that "; \ echo "certain data structures must always be 'static'"; \ exit 1; \ fi .PHONY: static-check # Check that assert.h is not used outside a whitelist of files. ALL_LOCAL += check-assert-h-usage check-assert-h-usage: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ (cd $(srcdir) && git --no-pager grep -l -E '[<]assert.h[>]') | \ $(EGREP) -v '^tests/'; \ then \ echo "Files listed above unexpectedly #include <""assert.h"">."; \ echo "Please use ovs_assert (from util.h) instead of assert."; \ exit 1; \ fi .PHONY: check-assert-h-usage # Check that LITTLE_ENDIAN and BIG_ENDIAN are not used unless BYTE_ORDER is # also mentioned. ( always defines the former two constants. They # must be compared to BYTE_ORDER to get the machine's correct endianness. But # it is better to use WORDS_BIGENDIAN.) ALL_LOCAL += check-endian check-endian: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ (cd $(srcdir) && git --no-pager grep -l -E \ -e 'BIG_ENDIAN|LITTLE_ENDIAN' --and --not -e 'BYTE_ORDER'); \ then \ echo "See above for list of files that misuse LITTLE""_ENDIAN"; \ echo "or BIG""_ENDIAN. Please use WORDS_BIGENDIAN instead."; \ exit 1; \ fi .PHONY: check-endian ALL_LOCAL += check-echo-n check-echo-n: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ git --no-pager grep -n 'echo'' -n' $(srcdir); \ then \ echo "See above for uses for \"echo"" -n\", which is non-POSIX"; \ echo "and does not work with all shells. Use \"printf\" instead."; \ exit 1; \ fi .PHONY: check-echo-n ALL_LOCAL += check-tabs check-tabs: @cd $(srcdir); \ if test -e .git && (git --version) >/dev/null 2>&1 && \ grep -ln "^ " \ `git ls-files | grep -v $(submodules) \ | grep -v -f build-aux/initial-tab-whitelist` /dev/null \ | $(EGREP) -v ':[ ]*/?\*'; \ then \ echo "See above for files that use tabs for indentation."; \ echo "Please use spaces instead."; \ exit 1; \ fi .PHONY: check-tabs ALL_LOCAL += thread-safety-check thread-safety-check: @cd $(srcdir); \ if test -e .git && (git --version) >/dev/null 2>&1 && \ grep -n -f build-aux/thread-safety-blacklist \ `git ls-files | grep -v $(submodules) | grep '\.[ch]$$'` /dev/null \ | $(EGREP) -v ':[ ]*/?\*'; \ then \ echo "See above for list of calls to functions that are"; \ echo "blacklisted due to thread safety issues"; \ exit 1; \ fi EXTRA_DIST += build-aux/thread-safety-blacklist .PHONY: thread-safety-check # Check that "ip" is used in preference to "ifconfig", because # "ifconfig" is not installed ubiquitously anymore. ALL_LOCAL += check-ifconfig check-ifconfig: @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \ (cd $(srcdir) && git --no-pager grep -l -E -e 'ifconfig' | \ $(EGREP) -v 'Makefile.am|ovs-vsctl-bashcomp|openvswitch-custom\.te'); \ then \ echo "See above for list of files that use or reference"; \ echo "'ifconfig'. Please use 'ip' instead."; \ exit 1; \ fi .PHONY: check-ifconfig northd_h = northd/northd.h action_h = include/ovn/actions.h checksum_file = lib/ovn-util.c # Check if northd stages and actions checksum is valid. ALL_LOCAL += check-northd check-northd: $(northd_h) $(action_h) $(checksum_file) @$(srcdir)/build-aux/cksum-pipeline-check $^ .PHONY: check-northd if HAVE_GROFF ALL_LOCAL += manpage-check manpage-check: $(man_MANS) $(dist_man_MANS) $(noinst_man_MANS) @error=false; \ for manpage in $?; do \ LANG=en_US.UTF-8 groff -w mac -w delim -w escape -w input -w missing -w tab -T utf8 -man -p -z $$manpage >$@.tmp 2>&1; \ if grep warning: $@.tmp; then error=:; fi; \ rm -f $@.tmp; \ done; \ if $$error; then exit 1; else touch $@; fi $(AM_V_GEN) touch -c $@ CLEANFILES += manpage-check endif if HAVE_FLAKE8 ALL_LOCAL += flake8-check # http://flake8.readthedocs.org/en/latest/user/error-codes.html # All warnings explicitly selected or ignored should be listed below. # # E***, W*** -- warnings from pep8 # E121 continuation line under-indented for hanging indent (only from flake8 v2.0) # E123 closing bracket does not match indentation of opening bracket's line # E125 continuation line with same indent as next logical line (only from flake8 v2.0) # E126 continuation line over-indented for hanging indent # E127 continuation line over-indented for visual indent # E128 continuation line under-indented for visual indent # E129 visually indented line with same indent as next logical line # E131 continuation line unaligned for hanging indent # E722 do not use bare except, specify exception instead # W503 line break before binary operator # W504 line break after binary operator # F*** -- warnings native to flake8 # F811 redefinition of unused from line (only from flake8 v2.0) # D*** -- warnings from flake8-docstrings plugin # H*** -- warnings from flake8 hacking plugin (custom style checks beyond PEP8) FLAKE8_IGNORE = E121,E123,E125,E126,E127,E128,E129,E131,E722,W503,W504,F811,D,H,I flake8-check: $(FLAKE8_PYFILES) $(FLAKE8_WERROR)$(AM_V_GEN) \ src='$^' && \ flake8 $$src --ignore=$(FLAKE8_IGNORE) $(FLAKE8_FLAGS) && \ touch $@ endif CLEANFILES += flake8-check include $(srcdir)/manpages.mk $(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py $(OVS_SRCDIR)/python/ovs_build_helpers/soutil.py @PYTHONPATH=$(OVS_SRCDIR)/python$(psep)$$PYTHONPATH$(psep)$(srcdir)/python $(PYTHON3) $(srcdir)/build-aux/sodepends.py -I. -Isrcdir,$(srcdir) -IOVS_MANDIR,$(OVS_MANDIR) $(MAN_ROOTS) >$(@F).tmp @if cmp -s $(@F).tmp $@; then \ touch $@; \ rm -f $(@F).tmp; \ else \ mv $(@F).tmp $@; \ fi CLEANFILES += manpage-dep-check if VSTUDIO_DDK ALL_LOCAL += ovsext ARCH = x64 ovsext: datapath-windows/ovsext.sln $(srcdir)/datapath-windows/include/OvsDpInterface.h if VSTUDIO_WIN8 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Build /property:Configuration="Win8$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif if VSTUDIO_WIN8_1 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Build /property:Configuration="Win8.1$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif if VSTUDIO_WIN10 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Build /property:Configuration="Win10$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif CLEAN_LOCAL += ovsext_clean ovsext_clean: datapath-windows/ovsext.sln if VSTUDIO_WIN8 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Clean /property:Configuration="Win8$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif if VSTUDIO_WIN8_1 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Clean /property:Configuration="Win8.1$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif if VSTUDIO_WIN10 MSBuild.exe //nologo //maxcpucount datapath-windows/ovsext.sln /target:Clean /property:Configuration="Win10$(VSTUDIO_CONFIG)" /property:Version="$(PACKAGE_VERSION)" //p:Platform=$(ARCH) endif endif .PHONY: ovsext clang-analyze: clean @which clang scan-build >/dev/null 2>&1 || \ (echo "Unable to find clang/scan-build, Install clang,clang-analyzer packages"; exit 1) @$(MKDIR_P) "$(srcdir)/tests/clang-analyzer-results" @scan-build -o $(srcdir)/tests/clang-analyzer-results --use-cc=$(CC) $(MAKE) .PHONY: clang-analyze dist-hook: $(DIST_HOOKS) all-local: $(ALL_LOCAL) clean-local: $(CLEAN_LOCAL) install-data-local: $(INSTALL_DATA_LOCAL) uninstall-local: $(UNINSTALL_LOCAL) .PHONY: $(DIST_HOOKS) $(CLEAN_LOCAL) $(INSTALL_DATA_LOCAL) $(UNINSTALL_LOCAL) dist-docs: VERSION=$(VERSION) MAKE='$(MAKE)' $(srcdir)/build-aux/dist-docs $(srcdir) $(docs) .PHONY: dist-docs include automake.mk include Documentation/automake.mk include m4/automake.mk include lib/automake.mk include utilities/automake.mk include tests/automake.mk include include/automake.mk include debian/automake.mk include lib/ovsdb_automake.mk include rhel/automake.mk include tutorial/automake.mk include controller/automake.mk include controller-vtep/automake.mk include northd/automake.mk include ic/automake.mk include build-aux/automake.mk ovn-25.09.0~git20250813.23884f5/NEWS000066400000000000000000003231651504532661100156560ustar00rootroot00000000000000Post v25.03.0 ------------- - STT tunnels are no longer supported in ovn-encap-type. ** WARNING ** Existing setups must be fully reconfigured to use Geneve or VxLAN before upgrading. To avoid potential database conversion issues all OVN databases should be manually compacted after the reconfiguration. For instructions see: https://docs.openvswitch.org/en/latest/ref/ovsdb.7/#compacting-databases - Added support for "ovn-cleanup-on-exit" config option in Open_vSwitch external-ids, this option allows to specify if ovn-controller should perform cleanup when exiting. The "--restart" exit always has priority to keep the backward compatibility. - Add additional protocol support for options:activation-strategy. The new supported protocols are gARP and NA. The option now supports a comma separated to specify selected group of protocols. - Add CoPP support for DHCP relay. - SSL/TLS: * Support for deprecated TLSv1 and TLSv1.1 protocols on OpenFlow and database connections is now removed. - Introduce exclude-router-ips-from-garp in logical_switch_port column so that the router port IPs are not advertised in the GARPs. - Added support for port mirroring in OVN overlay. - Added "ic-route-filter-adv" and "ic-route-filter-learn" options to the Logical_Router/Logical_Router_Port tables to allow users to filter advertised/learned IC routes. - Add a new logical switch option - enable-stateless-acl-lb with default value of false. This option should be set to true for logical switches with stateless ACL to work with load balancer. - Added new ovn-nbctl command 'pg-get-ports' to get the ports assigned to the port group. - The ovn-controller option ovn-ofctrl-wait-before-clear is no longer supported. It will be ignored if used. ovn-controller will automatically care about proper delay before clearing lflow. - Added "ic-route-adv-lb" and "ic-route-learn-lb" NB_Global:options to to allow advertising load balancer VIPs through OVN-IC. - Added a new ACL option "--all" to "acl-list" command. When set, "acl-list" command will also list port groups ACLs associated with each port of the target logical switch. - Adjusted priorities of src-ip based static routes to be lower than other types of routes regardless of prefix length. - Added support for running tests from the 'check-kernel' system test target under retis by setting OVS_TEST_WITH_RETIS=yes. See the 'Testing' section of the documentation for more details. - Dynamic Routing: * Add the option "dynamic-routing-redistribute-local-only" to Logical Routers and Logical Router Ports which refines the way in which chassis-specific Advertised_Routes (e.g., for NAT and LB IPs) are advertised. OVN v25.03.0 - 07 Mar 2025 -------------------------- - Added support to choose selection methods - dp_hash or hash (with specified hash fields) for ECMP routes while choosing nexthop. - ovn-ic: Add support for route tag to prevent route learning. - Support for STT tunnels in ovn-encap-type is deprecated and will be removed in the next release. - The LRP option 'centralize_routing' has been removed. The behavior is now enabled in all cases where it is needed. - ovn-nb: Changed schema of ovn-nb to make networks optional within Logical Router Ports. - Added support for Spine-Leaf topology of logical switches by adding a new LSP type 'switch' that can directly connect two logical switches. Supported for both distributed and transit switches. - Bump python version required for building OVN to 3.7. - SSL/TLS: * TLSv1 and TLSv1.1 protocols are deprecated and disabled by default on OpenFlow and database connections. Use --ssl-protocols to turn them back on. Support will be fully removed in the next release. * OpenSSL 1.1.1 or newer is now required for SSL/TLS support. * The protocol list in --ssl-protocols or corresponding database column now supports specifying simple protocol ranges like: - "TLSv1-TLSv1.2" to enable all protocols between TLSv1 and TLSv1.2. - "TLSv1.2+" to enable protocol TLSv1.2 and later. The value must be a list of protocols or exactly one protocol range. * Added explicit support for TLSv1.3. It can now be enabled via --ssl-protocols (TLSv1.3 was supported in earlier versions only when this option was not set). TLS ciphersuites for TLSv1.3 and later can be configured via --ssl-ciphersuites (--ssl-ciphers only applies to TLSv1.2 and earlier). - Add "arp-nd-max-timeout-sec" config option to vswitchd external-ids to configure the interval (in seconds) between ovn-controller originated ARP/ND packets used for tracking ECMP next hop MAC addresses. - Auto flush ECMP symmetric reply connection states when an ECMP route is removed by the CMS. This behavior is controlled by the "ecmp_nexthop_monitor_enable" config option in the NB_Global table. Disabled by default. - Improved handling of IPv6 traffic by enabling address prefix tracking in OVS for both IPv4 and IPv6 addresses, whenever possible, reducing the amount of IPv6 datapath flows. - Add concept of Transit Routers, users are now allowed to specify options:requested-chassis for router ports; if the chassis is remote then the router port will behave as a remote port. - Added a new ACL option "persist-established" that allows for established connections to bypass ACL matching. This way, if an ACL match changes, traffic on the established connection can still pass. - Logical router policies can now be arranged in chains. Using the new "jump" action, combined with new "chain" and "jump_chain" columns, allows for policies to be chained together. - Reduce the max number of local datapath to 1024 when OVN is using VXLAN encapsulation type in OVN-interconnect mode. - Added vxlan_mode parameter in IC_NB_GLOBAL option column to enable or disable VXLAN encapsulation type in OVN-interconnect mode. - Dynamic Routing: * Add the option "dynamic-routing" to Logical Routers. If set to true static and connected routes matching the filter below are shared to the southbound "Advertised_Route" table for sharing outside of OVN. The routes can further be configured by setting `dynamic-routing-redistribute` on the LR or LRP. The LRP settings overwrite the LR settings for all routes using this interface to forward traffic on. * Allow Logical Routers to dynamically learn routes from outside the fabric. Routes entered into the "Learned_Route" table in the southbound database will be learned by the respective LR. They are included in the route table with a lower priority than static routes. * Add the option value "connected-as-host" to the "dynamic-routing-redistribute" LR and LRP option. If set then connected routes are announced as individual host routes. * Add the option "dynamic-routing-maintain-vrf" to LRPs. If set the ovn-controller will create a vrf named "ovnvrf" + datapath id that includes all advertised and learned routes. The vrf name can be overwritten with the "dynamic-routing-vrf-name" setting. * Add the option "dynamic-routing-port-name" to LRPs. If set only routes learned from a linux interfaces that is locally bound to the referenced LSP will be learned. Additionally support local overwrites for arbitrary interface names using "dynamic-routing-port-mapping". * The logical router port options "routing-protocol-redirect" and "routing-protocols" are now also usable on distributed gateway ports. * Logical router port options "routing-protocol-redirect" and "routing-protocols" are now considered stable. Their "experimental" tag was removed. - Add "options:ct-commit-all" to LR, that enables commit of all traffic to DNAT and SNAT zone when LR is stateful. OVN v24.09.0 - 13 Sep 2024 -------------------------- - Added a new logical switch port option "pkt_clone_type". If the value is set to "mc_unknown", packets destined to the port gets cloned to all unknown ports connected to the same Logical Switch. - Added a new logical switch port option "disable_arp_nd_rsp" to disable adding the ARP responder flows if set to true. - IGMP_Group has new "protocol" column that displays the the group protocol version. - Add ovn-debug tool containing two commands. "lflow-stage-to-ltable STAGE_NAME" that converts stage name into logical flow table id. "lflow-stage-to-oftable STAGE_NAME" that converts stage name into OpenFlow table id. - Rename the ovs-sandbox script to ovn-sandbox. - Remove "ovn-set-local-ip" config option from vswitchd external-ids, the option is no longer needed as it became effectively "true" for all scenarios. - Added DHCPv4 relay support. - A new LSP option "force_fdb_lookup" has been added to ensure the additional MAC addresses configured on the LSP with "unknown", are learnt via the OVN native FDB. - Add support for ovsdb-server `--config-file` option in ovn-ctl. - Add "ovn-bridge-remote" config option to vswitchd external-ids, that allows to specify connection method to management bridge for ovn-controller, defaulting to the unix socket. - Add "ovn-bridge-remote-probe-interval" config option to vswitchd external-ids, that sets probe interval for integration bridge connection, disabled by default. - The "options:ic-route-blacklist" option in the Northbound NB_Global table has been renamed to "options:ic-route-denylist" in order to comply with inclusive language guidelines. The previous name is still recognized to aid with backwards compatibility. - NATs can now be given an arbitrary match condition and priority. This allows for conditional NATs to be configured. See the ovn-nb(5) man page for more information. - Added new global config option NB_Global:options:vxlan_mode to support ability to disable "VXLAN mode" to extend available tunnel IDs space for datapaths from 4095 to 16711680. For more details see man ovn-nb(5) for mentioned option. - Added new global config option NB_Global:options:always_tunnel. If set to true, the traffic destined to a logical port of a provider logical switch (having a localnet port) will be tunnelled instead of sending it via the localnet port. - Added support to define boundaries (min and max values) for selected ct zones. - Add support for CT zone limit that can be specified per LR (options:ct-zone-limit), LS (other_config:ct-zone-limit) or LSP (options:ct-zone-limit). - A new LSP option "disable_garp_rarp" has been added to prevent OVN from sending GARP or RARP announcements when a VIF is created on a bridged logical switch. - A new LRP option 'centralize_routing' has been added to a distributed gateway port to centralize routing if the logical switch of its peer doesn't have a localnet port. - The NB_Global.debug_drop_domain_id configured value is now overridden by the ID associated with the Sampling_App record created for drop sampling (Sampling_App.type configured as "drop"). - Add support for ACL sampling through the new Sample_Collector and Sample tables. Sampling is supported for both traffic that creates new connections and for traffic that is part of an existing connection. - Add "external_ids:ovn-encap-ip-default" config for ovn-controller to determine the default encap IP when there are multiple encap IPs configured. - Added a new column in the southbound database "flow_desc" to provide human readable context to flows. - Added two new experimental logical router port options, "routing-protocol-redirect" and "routing-protocols", that allow redirection of routing protocol traffic received by a router port to a different logical switch port. - Allow Static Routes where the address families of ip_prefix and nexthop diverge (e.g. IPv4 packets over IPv6 links). This is currently limited to nexthops that have their mac addresses prepopulated (so dynamic_neigh_routers must be false). OVN v24.03.0 - 01 Mar 2024 -------------------------- - DNS now have an "options" column for configuration of extra options. - A new DNS option "ovn-owned" has been added to allow defining domains that are owned only by ovn, queries for that domain will not be processed externally. - Disable OpenFlow inactivity probing between ovn-controller and OVS. OF connection is established over unix socket, which is a reliable connection method and doesn't require additional probing. external_ids:ovn-openflow-probe-interval configuration option for ovn-controller no longer matters and is ignored. - Support CIDR based MAC binding aging threshold. See ovn-nb(5) for 'mac_binding_age_threshold' for more details. - ovn-northd-ddlog has been removed. - A new LSP option "enable_router_port_acl" has been added to enable conntrack for the router port whose peer is l3dgw_port if set it true. - Enable PMTU discovery on geneve/vxlan tunnels for E/W traffic. - Support selecting encapsulation IP based on the source/destination VIF's settting. See ovn-controller(8) 'external_ids:ovn-encap-ip' for more details. - Introduce next-hop BFD availability check for OVN reroute policies. - Add the capability to mark (through pkt.mark) incoming/outgoing packets in the logical switch datapath according to user configured QoS rule. - OVN Interconnection: * INB provides basic feedback to the CMS about the ISB changes handling status. * IC_NB_Global now have "nb_ic_cfg" and "sb_ic_cfg" columns for for ISB informational status. * IC_SB_Global now have "nb_ic_cfg" column for ISB informational status. * Availability_Zone now have "nb_ic_cfg" column for local AZ informational status. OVN v23.09.0 - 15 Sep 2023 -------------------------- - Added FDB aging mechanism, that is disabled by default. It can be enabled per logical switch with other_config "fdb_age_threshold". - Add DHCPv6 "fqdn" (39) option, that works similarly to DHCPv4 "hostname" (12) option. - Support to create/update MAC_Binding when GARP received from VTEP (RAMP) switch on l3dgw port. - To allow optimizing ovn-controller's monitor conditions for the regular VIF case, ovn-controller now unconditionally monitors all sub-ports (ports with parent_port set). - ECMP routes use L4_SYM dp-hash by default if the datapath supports it. Existing sessions might get re-hashed to a different ECMP path when OVN detects the algorithm support in the datapath during an upgrade or restart of ovn-controller. - Add "northd-backoff-interval-ms" config option to delay northd engine runs capped at the set value. - Add "garp-max-timeout-sec" config option to vswitchd external-ids to cap the time between when ovn-controller sends gARP packets. - Introduce support for binding remote ports in ovn-northd if the CMS sets requested-chassis option for a remote logical switch port. - Added support to reply success for DHCPv6 Release messages. OVN v23.06.0 - 01 Jun 2023 -------------------------- - Enhance LSP.options:arp_proxy to support IPv6, configurable MAC addresses and CIDRs. - CT entries are not flushed by default anymore whenever a load balancer backend is removed. A new, per-LB, option 'ct_flush' can be used to restore the previous behavior. Disabled by default. - Add support to configure OVSDB inactivity probe interval for ovn-ic and ovn-controller-vtep. - Add LS.other_config:broadcast-arps-to-all-routers. If false then arp requests are only send to Logical Routers on that Logical Switch if the target mac address matches. Arp requests matching no Logical Router will only be forwarded to non-router ports. Default is true which keeps the existing behaviour of flooding these arp requests to all attached Ports. - Always allow IPv6 Router Discovery, Neighbor Discovery, and Multicast Listener Discovery protocols, regardless of ACLs defined. - Add IPv6 iPXE support introducing "bootfile_name" (59) and "bootfile_name_alt" (254) options to ovn dhcpv6 server. - Support using local OVS port as port-mirroring target, and also support 'both' directions for the 'filter' field. - Increased ovn-{ic-,}{n,s}bctl default OVSDB inactivity probe interval from 5000 ms to 120000 ms to give the ability to connect to large databases (mainly, OVN_Southbound). Also, for daemon mode it is possible to configure inactivity probe interval via OVN_Northbound and OVN_Southbound databases for ovn-nbctl and ovn-sbctl respectively. See man ovn-nb and man ovn-sb for 'nbctl_probe_interval' and 'sbctl_probe_interval' options for more details. - Rework OVN egress QoS implementation in order to rely on OvS interface instead of directly running tc from OVN. Get rid of traffic shaping on the tunnel interfaces. Now for LSPs running on a LogicalSwitch with a localnet port is possible to define QoS rules to apply to the local egress localnet port. Please note now the QoS will be applied just to the local localnet port and not to all localnet port marked with ovn-egress iface. - Support for tiered ACLs has been added. This allows for ACLs to be layered into separate tiers of priority. For more information, please see the ovn-nb and ovn-northd manpages. - Send ICMP Fragmentation Needed packets back to offending ports when communicating with multichassis ports using frames that don't fit through a tunnel. This is done only for logical switches that are attached to a physical network via a localnet port, in which case multichassis ports may have an effective MTU different from regular ports and hence may need this mechanism to maintain connectivity with other peers in the network. OVN v23.03.0 - 03 Mar 2023 -------------------------- - ovn-controller: Experimental support for co-hosting multiple controller instances on the same host. - Add ovn-ctl commands for (re)starting/stopping OVSDB relay for OVN SB DB. - Add new ovn-db@.service systemd unit to run ovsdb-servers in separate systemd units. OVN v22.12.0 - 16 Dec 2022 -------------------------- - Add load balancer "affinity_timeout" option to configure load balancing of traffic from a particular client to the same backend for a given period of time. - ovn-northd: Add configuration knobs to enable drop sampling using OVS's per-flow IPFIX sampling. - Add support for component templates within logical flows and load balancers. - Add support for remote port mirroring (Experimental). - Add new OVN IC Route table index. This index ensures no duplicate routes can be advertized. When upgrading to this version user must ensure that all ovn-ic daemons in all availability zones are upgraded before ovn-ic SB database schema is converted. OVN v22.09.0 - 16 Sep 2022 -------------------------- - ovn-controller: Add configuration knob, through OVS external-id "ovn-encap-df_default" to enable or disable tunnel DF flag. - Add option "localnet_learn_fdb" to LSP that will allow localnet ports to learn MAC addresses and store them in FDB table. - northd: introduce the capability to automatically deploy a load-balancer on each logical-switch connected to a logical router where the load-balancer has been installed by the CMS. In order to enable the feature the CMS has to set install_ls_lb_from_router to true in option column of NB_Global table. - Added nb_global IPsec options ipsec_encapsulation=true (libreswan) and ipsec_forceencaps=true (strongswan) to unconditionally enforce NAT-T UDP encapsulation. Requires OVS support for IPsec custom tunnel options (which is available in OVS 3.0). - Removed possibility of disabling logical datapath groups. - Removed the copying of SB's Chassis other_config into external_ids. - Added MAC binding aging mechanism, that is disabled by default. It can be enabled per logical router with option "mac_binding_age_threshold". - If it is needed to create Load Balancer within LR with VIP, which matches any of LR's LRP IP, there is no need to create SNAT entry. Now such traffic destined to LRP IP is not dropped. - Bump python version required for building OVN to 3.6. OVN v22.06.0 - 03 Jun 2022 -------------------------- - Support IGMP and MLD snooping on transit logical switches that connect different OVN Interconnection availability zones. - Replaced the usage of masked ct_label by ct_mark in most cases to work better with hardware-offloading. - Support NAT for logical routers with multiple distributed gateway ports. - Add global option (NB_Global.options:default_acl_drop) to enable implicit drop behavior on logical switches with ACLs applied. - Support (LSP.options:qos_min_rate) to guarantee minimal bandwidth available for a logical port. - Add NB.Load_Balancer.options:neighbor_responder to allow the CMS to explicitly request routers to reply to any ARP/ND request for a VIP (when set to "all") and only for reachable VIPs (when set to "reachable" or by default). - Changed the way to enable northd parallelization. Removed support for: - use_parallel_build in NBDB. - --dummy-numa in northd cmdline. Added support for: - --n-threads= in northd cmdline. - set-n-threads/get-n-threads unixctls. - --ovn-northd-n-threads command line argument in ovn-ctl - Added support for setting the Next server IP in the DHCP header using the private DHCP option - 253 in native OVN DHCPv4 responder. - Support list of chassis for Logical_Switch_Port:options:requested-chassis. - Support Logical_Switch_Port:options:activation-strategy for live migration scenarios. OVN v22.03.0 - 11 Mar 2022 -------------------------- - Refactor CoPP commands introducing a unique name index in CoPP NB table. Add following new CoPP commands to manage CoPP table: - ovn-nbctl copp-add - ovn-nbctl copp-del - ovn-nbctl copp-list - ovn-nbctl ls-copp-add - ovn-nbctl lr-copp-add - Support version pinning between ovn-northd and ovn-controller-vtep as an option. If the option is enabled and the versions don't match, ovn-controller-vtep will not process any DB changes. - When configured to log packtes matching ACLs, log the direction (logical pipeline) too. - Introduce exclude-lb-vips-from-garp in logical_switch_port column in order to not advertise lbs VIPs in GARPs sent by the logical router. - ACLs now have an "options" column for configuration of extra options. - A new ACL option, "log-related" has been added that allows for reply and related traffic to be logged for an ACL in addition to the traffic that directly matches the ACL. OVN v21.12.0 - 22 Dec 2021 -------------------------- - Set ignore_lsp_down to true as default, so that ARP responder flows are installed together with other flows when a logical switch port is created, without having to wait for the port to be UP. CMS should set it to false if not desired. - Added Load_Balancer_Group support, which simplifies large scale configurations of load balancers. - Introduced infrastructure for VIF plug providers. When OVN is linked with an appropriate VIF plug provider CMS can request OVN to plug lports. This is particularly useful in topologies where the ovn-controller process is running on SmartNIC control plane CPUs. Please refer to Documentation/topics/vif-plug-providers/vif-plug-providers.rst for more information. - Added Logical_Router_Port "gateway_mtu_bypass" option. - Added new "inc-engine/recompute" command to all incremental processing engine clients (ovn-northd and ovn-controller). - ovn-controller: Add configuration knob, through OVS external-id "ovn-trim-timeout-ms" to allow specifiying an lflow cache inactivity timeout after which ovn-controller should trim memory. OVN v21.09.0 - 01 Oct 2021 -------------------------- - Added Control Plane Protection support (control plane traffic metering). - Added path MTU discovery for ingress traffic originated outside of the cluster. - Introduced a new "label" field for "allow" and "allow-related" ACLs which helps in debugging/backtracking the ACL which allowed a particular connection. - Allow static routes without nexthops. - Enabled logical dp groups as a default. CMS should disable it if not desired. - Added support for multiple routing tables in Logical Router Static Routes and LRPs. OVN Interconnection supports routes' route tables as well. This requires to update schemas for OVN_Northdbound and OVN_IC_Southbound DBs. OVN v21.06.0 - 18 Jun 2021 ------------------------- - ovn-northd-ddlog: New implementation of northd, based on DDlog. This implementation is incremental, meaning that it only recalculates what is needed for the southbound database when northbound changes occur. It is expected to scale better than the C implementation, for large deployments. (This may take testing and tuning to be effective.) This version of OVN requires DDLog 0.38. - Introduce ovn-controller incremental processing engine statistics - Introduced parallel processing in ovn-northd with the NB_Global config option 'use_parallel_build' to enable it. It is disabled by default. - Support vlan-passthru mode for tag=0 localnet ports. - Support custom 802.11ad EthType for localnet ports. - Add a new NB Global option - use_ct_inv_match with the default value of true. If this is set to false, then the logical field - "ct.inv" will not be used in the logical flow matches. CMS can consider setting this to false, if they want to use smart NICs which don't support offloading datapath flows with this field used. - Introduce a new "allow-stateless" ACL verb to always bypass connection tracking. The existing "allow" verb behavior is left intact. - Added support in native DNS to respond to PTR request types. - ovn-nbctl daemon mode is no longer considered experimental. - Utilities: * ovn-nbctl daemon mode is no longer considered experimental. * ovn-sbctl now also supports daemon mode. - Added support in native DNS to respond to PTR request types. - New --dry-run option for ovn-northd and ovn-northd-ddlog. - ovn-controller: Add configuration knobs, through OVS external-id "ovn-trim-limit-lflow-cache" and "ovn-trim-wmark-perc-lflow-cache", to allow enforcing a lflow cache size limit and high watermark percentage for which automatic memory trimming is performed. - Support multiple distributed gateway ports on a single logical router. (NAT and load-balancer are not supported yet when there are multiple distributed gateway ports). OVN v21.03.0 - 12 Mar 2021 ------------------------- - Support ECMP multiple nexthops for reroute router policies. - BFD protocol support according to RFC880 [0]. Introduce next-hop BFD availability check for OVN static routes. [0] https://tools.ietf.org/html/rfc5880) - Change the semantic of the "Logical_Switch_Port.up" field such that it is set to "true" only when all corresponding OVS openflow operations have been processed. This also introduces a new "OVS.Interface.external-id", "ovn-installed". This external-id is set by ovn-controller only after all openflow operations corresponding to the OVS interface being added have been processed. - ovn-ctl: Added new command line argument '--ovsdb-disable-file-column-diff' to support ovsdb-server upgrades from version 2.14 and earlier to 2.15 and later. See ovsdb(7) for more details. - Add a new option to Load_Balancer.options, "hairpin_snat_ip", to allow users to explicitly select which source IP should be used for load balancer hairpin traffic. - ovn-controller: Add configuration knobs, through OVS external-id "ovn-limit-lflow-cache" and "ovn-memlimit-lflow-cache-kb", to allow enforcing a limit for the size of the logical flow cache based on maximum number of entries and/or memory usage. - ovn-controller: Add lflow cache related memory reports. OVN v20.12.0 - 18 Dec 2020 -------------------------- - The "datapath" argument to ovn-trace is now optional, since the datapath can be inferred from the inport (which is required). - The obsolete "redirect-chassis" way to configure gateways has been removed. See ovn-nb(5) for advice on how to update your config if needed. - Add IPv4 iPXE support introducing "bootfile_name_alt" option to ovn dhcp server. - Support other_config:vlan-passthru=true to allow VLAN tagged incoming traffic. - Propagate currently processed SB_Global.nb_cfg in ovn-controller to the local OVS DB integration bridge external_ids:ovn-nb-cfg. - Support version pinning between ovn-northd and ovn-controller as an option. If the option is enabled and the versions don't match, ovn-controller will not process any DB changes. - Add "fair" column in Meter table to allow multiple ACL logs to use the same Meter while being rate-limited independently. - New configuration option for northd 'options:use_logical_dp_groups=true' to enable combining of logical flows by logical datapath. This should significantly decrease size of a Southbound DB. However, in some cases, it could have performance penalty for ovn-controller. Disabled by default. OVN v20.09.0 - 28 Sep 2020 -------------------------- - Added packet marking support for traffic routed with a routing policy. - Added DHCPINFORM and DHCPRELEASE support in native OVN DHCPv4 responder. - Added support for DHCP domain search option (119) in native OVN DHCPv4 responder. - The nb_cfg column from the Chassis table in the OVN Southbound database has been deprecated and is no longer updated. A new table called Chassis_Private now contains the nb_cfg column which is updated by incrementing the value in the NB_Global table, CMSes relying on this mechanism should update their code to use this new table. - Added support for external ip based NAT. Now, besides the logical ip, external ips will also decide if a packet will be NATed or not. - Added support for VXLAN encapsulation (not just for ramp/VTEP switches). OVN v20.06.0 -------------------------- - Added support for external_port_range in NAT table. - ovn-controller no longer monitor the external_ids column from the Chassis table. This was done to avoid having to do a flow recalculation every time external systems wrote to this column. The chassis configuration has now being moved to a new column called "other_config". As a note, the configurations are still be written to the external_ids column (but no longer triggers an alert) to keep the backward compatibility with current systems that may be reading it from that column but, this behavior will be removed in the future. - Added IPv6 Prefix Delegation support in OVN. - OVN now uses OpenFlow 1.5. - Added support to choose selection methods - dp_hash or hash (with specified hash fields) for OVN load balancer backend selection. This is incompatible with older versions. Care should be taken while upgrading as the existing load balancer traffic will be affected if ovn-controllers are not stopped before uprading northd services. - Added limited support for logical switches with multiple localnet ports. The feature requires that no chassis has two or more physical networks with localnet ports that belong to the same logical switch mapped. Routing between the ports to be implemented by fabric. - OVN Interconnection: * Support for L3 interconnection of multiple OVN deployments with tunnels managed by OVN. See instructions in Documentation/tutorials/ovn-interconnection.rst. OVN v20.03.0 - 04 Feb 2020 -------------------------- - OVN was split out from the OVS repository and is now released independently. - Added IPv6 NAT support for OVN routers. - Added Stateless Floating IP support in OVN. - Added Forwarding Group support in OVN. - Added support for MLD Snooping and MLD Querier. - Added support for ECMP routes in OVN router. v2.12.0 - 03 Sep 2019 --------------------- - DPDK: * New option 'other_config:dpdk-socket-limit' to limit amount of hugepage memory that can be used by DPDK. * Add support for vHost Post-copy Live Migration (experimental). * OVS validated with DPDK 18.11.2 which is the new minimal supported version. * DPDK 18.11.1 and lower is no longer supported. * New option 'tx-retries-max' to set the maximum amount of vhost tx retries that can be made. - OpenFlow: * All features required by OpenFlow 1.5 are now implemented, so ovs-vswitchd now enables OpenFlow 1.5 by default (in addition to OpenFlow 1.0 to 1.4). * Removed support for OpenFlow 1.6 (draft), which ONF abandoned. * New action "check_pkt_larger". * Support for OpenFlow 1.5 "meter" action. - Userspace datapath: * ICMPv6 ND enhancements: support for match and set ND options type and reserved fields. * Add v4/v6 fragmentation support for conntrack. * New ovs-appctl "dpctl/ipf-set-enabled" and "dpctl/ipf-set-disabled" commands for userspace datapath conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-min-frag" command for userspace datapath conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-set-max-nfrags" command for userspace datapath conntrack fragmentation support. * New "ovs-appctl dpctl/ipf-get-status" command for userspace datapath conntrack fragmentation support. * New action "check_pkt_len". * Port configuration with "other-config:priority-tags" now has a mode that retains the 802.1Q header even if VLAN and priority are both zero. * 'ovs-appctl exit' now implies cleanup of non-internal ports in userspace datapath regardless of '--cleanup' option. Use '--cleanup' to remove internal ports too. * Removed experimental tag for SMC cache. * Datapath classifer code refactored to enable function pointers to select the lookup implementation at runtime. This enables specialization of specific subtables based on the miniflow attributes, enhancing the performance of the subtable search. * Add Linux AF_XDP support through a new experimental netdev type "afxdp". - OVSDB: * OVSDB clients can now resynchronize with clustered servers much more quickly after a brief disconnection, saving bandwidth and CPU time. See section 4.1.15 of ovsdb-server(7) for details of related OVSDB protocol extension. * Support to convert from cluster database to standalone database is now available when clustered is down and cannot be revived using ovsdb-tool . Check "Database Migration Commands" in ovsdb-tool man section. - OVN: * IPAM/MACAM: - select IPAM mac_prefix in a random manner if not provided by the user - add the capability to specify a static IPv4 and/or IPv6 address and get the L2 one allocated dynamically using the following syntax: ovn-nbctl lsp-set-addresses "dynamic " * Added the HA chassis group support. * Added 'external' logical port support. * Added Policy-based routing(PBR) support to create permit/deny/reroute policies on the logical router. New table(Logical_Router_Policy) added in OVN-NB schema. New "ovn-nbctl" commands to add/delete/list PBR policies. * Support for Transport Zones, a way to separate chassis into logical groups which results in tunnels only been formed between members of the same transport zone(s). * Support for IGMP Snooping and IGMP Querier. - New QoS type "linux-netem" on Linux. - Added support for TLS Server Name Indication (SNI). - Linux datapath: * Support for the kernel versions 4.19.x and 4.20.x. * Support for the kernel version 5.0.x. * Add support for conntrack zone-based timeout policy. - 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows. 'ovs-appctl dpctl/dump-flows' should be used instead. - Add L2 GRE tunnel over IPv6 support. v2.11.0 - 19 Feb 2019 --------------------- - OpenFlow: * OFPMP_TABLE_FEATURES_REQUEST can now modify table features. - ovs-ofctl: * "mod-table" command can now change OpenFlow table names. - ovn: * OVN-SB schema changed: duplicated IP with same Encapsulation type is not allowed any more. Please refer to Documentation/intro/install/ovn-upgrades.rst for the instructions in case there are problems encountered when upgrading from an earlier version. * New support for IPSEC encrypted tunnels between hypervisors. * ovn-ctl: allow passing user:group ids to the OVN daemons. * IPAM/MACAM: - add the capability to dynamically assign just L2 addresses - add the capability to specify a static ip address and get the L2 one allocated dynamically using the following syntax: ovn-nbctl lsp-set-addresses "dynamic " - DPDK: * Add support for DPDK 18.11 * Add support for port representors. - Userspace datapath: * Add option for simple round-robin based Rxq to PMD assignment. It can be set with pmd-rxq-assign. * Add support for Auto load balancing of PMDs (experimental) * Added new per-port configurable option to manage EMC: 'other_config:emc-enable'. - Add 'symmetric_l3' hash function. - OVS now honors 'updelay' and 'downdelay' for bonds with LACP configured. - ovs-vswitchd: * New configuration option "offload-rebalance", that enables dynamic rebalancing of offloaded flows. - The environment variable OVS_SYSLOG_METHOD, if set, is now used as the default syslog method. - The environment variable OVS_CTL_TIMEOUT, if set, is now used as the default timeout for control utilities. - The environment variable OVS_RESOLV_CONF, if set, is now used as the DNS server configuration file. - RHEL packaging: * OVN packages are split from OVS packages. A new spec file - ovn-fedora.spec.in is added to generate OVN packages. - Linux datapath: * Support for the kernel versions 4.16.x, 4.17.x, and 4.18.x. v2.10.0 - 18 Aug 2018 --------------------- - ovs-vswitchd and utilities now support DNS names in OpenFlow and OVSDB remotes. - ovs-vswitchd: * New options --l7 and --l7-len to "ofproto/trace" command. * Previous versions gave OpenFlow tables default names of the form "table#". These are not helpful names for the purpose of accepting and displaying table names, so now tables by default have no names. * The "null" interface type, deprecated since 2013, has been removed. * Add minimum network namespace support for Linux. * New command "lacp/show-stats" - ovs-ofctl: * ovs-ofctl now accepts and display table names in place of numbers. By default it always accepts names and in interactive use it displays them; use --names or --no-names to override. See ovs-ofctl(8) for details. - ovs-vsctl: New commands "add-bond-iface" and "del-bond-iface". - ovs-dpctl: * New commands "ct-set-limits", "ct-del-limits", and "ct-get-limits". - OpenFlow: * OFPT_ROLE_STATUS is now available in OpenFlow 1.3. * OpenFlow 1.5 extensible statistics (OXS) now implemented. * New OpenFlow 1.0 extensions for group support. * Default selection method for select groups is now dp_hash with improved accuracy. - Linux datapath * Add support for compiling OVS with the latest Linux 4.14 kernel. * Added support for meters. * Add support for conntrack zone limit. - ovn: * Implemented icmp4/icmp6/tcp_reset actions in order to drop the packet and reply with a RST for TCP or ICMPv4/ICMPv6 unreachable message for other IPv4/IPv6-based protocols whenever a reject ACL rule is hit. * ACL match conditions can now match on Port_Groups as well as address sets that are automatically generated by Port_Groups. ACLs can be applied directly to Port_Groups as well. * ovn-nbctl can now run as a daemon (long-lived, background process). See ovn-nbctl(8) for details. - DPDK: * New 'check-dpdk' Makefile target to run a new system testsuite. See Testing topic for the details. * Add LSC interrupt support for DPDK physical devices. * Allow init to fail and record DPDK status/version in OVS database. * Add experimental flow hardware offload support * Support both shared and per port mempools for DPDK devices. - Userspace datapath: * Commands ovs-appctl dpif-netdev/pmd-*-show can now work on a single PMD * Detailed PMD performance metrics available with new command ovs-appctl dpif-netdev/pmd-perf-show * Supervision of PMD performance metrics and logging of suspicious iterations * Add signature match cache (SMC) as experimental feature. When turned on, it improves throughput when traffic has many more flows than EMC size. - ERSPAN: * Implemented ERSPAN protocol (draft-foschiano-erspan-00.txt) for both kernel datapath and userspace datapath. * Added port-based and flow-based ERSPAN tunnel port support, added OpenFlow rules matching ERSPAN fields. See ovs-fields(7). - ovs-pki * ovs-pki now generates x.509 version 3 certificate. The new format adds subjectAltName field and sets its value the same as common name (CN). v2.9.0 - 19 Feb 2018 -------------------- - NSH implementation now conforms to latest draft (draft-ietf-sfc-nsh-28). * Add ttl field. * Add a new action dec_nsh_ttl. * Enable NSH support in kernel datapath. - OVSDB has new, experimental support for database clustering: * New high-level documentation in ovsdb(7). * New file format documentation for developers in ovsdb(5). * Protocol documentation moved from ovsdb-server(1) to ovsdb-server(7). * ovsdb-server now supports online schema conversion via "ovsdb-client convert". * ovsdb-server now always hosts a built-in database named _Server. See ovsdb-server(5) for more details. * ovsdb-client: New "get-schema-cksum", "query", "backup", "restore", and "wait" commands. New --timeout option. * ovsdb-tool: New "create-cluster", "join-cluster", "db-cid", "db-sid", "db-local-address", "db-is-clustered", "db-is-standalone", "db-name", "schema-name", "compare-versions", and "check-cluster" commands. * ovsdb-server: New ovs-appctl commands for managing clusters. * ovs-sandbox: New support for clustered databases. - ovs-vsctl and other commands that display data in tables now support a --max-column-width option to limit column width. - No longer slow-path traffic that sends to a controller. Applications, such as OVN ACL logging, want to send a copy of a packet to a controller while leaving the actual packet forwarding in the datapath. - OVN: * The "requested-chassis" option for a logical switch port now accepts a chassis "hostname" in addition to a chassis "name". * IPv6 - Added support to send IPv6 Router Advertisement packets in response to the IPv6 Router Solicitation packets from the VIF ports. - Added support to generate Neighbor Solicitation packets using the OVN action 'nd_ns' to resolve unknown next hop MAC addresses for the IPv6 packets. * Add support for QoS bandwidth limit with DPDK. * ovn-ctl: New commands run_nb_ovsdb and run_sb_ovsdb. * ovn-sbctl, ovn-nbctl: New options --leader-only, --no-leader-only. - OpenFlow: * ct_clear action is now backed by kernel datapath. Support is probed for when OVS starts. - Linux kernel 4.13 * Add support for compiling OVS with the latest Linux 4.13 kernel - ovs-dpctl and related ovs-appctl commands: * "flush-conntrack" now accept a 5-tuple to delete a specific connection tracking entry. * New "ct-set-maxconns", "ct-get-maxconns", and "ct-get-nconns" commands for userspace datapath. - No longer send packets to the Linux TAP device if it's DOWN unless it is in another networking namespace. - DPDK: * Add support for DPDK v17.11 * Add support for vHost IOMMU * New debug appctl command 'netdev-dpdk/get-mempool-info'. * All the netdev-dpdk appctl commands described in ovs-vswitchd man page. * Custom statistics: - DPDK physical ports now return custom set of "dropped", "error" and "management" statistics. - ovs-ofctl dump-ports command now prints new of set custom statistics if available (for OpenFlow 1.4+). * Switch from round-robin allocation of rxq to pmd assignments to a utilization-based allocation. * New appctl command 'dpif-netdev/pmd-rxq-rebalance' to rebalance rxq to pmd assignments. * Add rxq utilization of pmd to appctl 'dpif-netdev/pmd-rxq-show'. * Add support for vHost dequeue zero copy (experimental). - Userspace datapath: * Output packet batching support. - vswitchd: * Datapath IDs may now be specified as 0x1 (etc.) instead of 16 digits. * Configuring a controller, or unconfiguring all controllers, now deletes all groups and meters (as well as all flows). - New --enable-sparse configure option enables "sparse" checking by default. - Added additional information to vhost-user status. v2.8.0 - 31 Aug 2017 -------------------- - ovs-ofctl: * ovs-ofctl can now accept and display port names in place of numbers. By default it always accepts names and in interactive use it displays them; use --names or --no-names to override. See ovs-ofctl(8) for details. * "ovs-ofctl dump-flows" now accepts --no-stats to omit flow statistics. - New ovs-dpctl command "ct-stats-show" to show connection tracking stats. - Tunnels: * Added support to set packet mark for tunnel endpoint using `egress_pkt_mark` OVSDB option. * When using Linux kernel datapath tunnels may be created using rtnetlink. This will allow us to take advantage of new tunnel features without having to make changes to the vport modules. - EMC insertion probability is reduced to 1% and is configurable via the new 'other_config:emc-insert-inv-prob' option. - DPDK: * DPDK log messages redirected to OVS logging subsystem. Log level can be changed in a usual OVS way using 'ovs-appctl vlog' commands for 'dpdk' module. Lower bound still can be configured via extra arguments for DPDK EAL. * dpdkvhostuser ports are marked as deprecated. They will be removed in an upcoming release. * Support for DPDK v17.05.1. - IPFIX now provides additional counters: * Total counters since metering process startup. * Per-flow TCP flag counters. * Multicast, broadcast, and unicast counters. - New support for multiple VLANs (802.1ad or "QinQ"), including a new "dot1q-tunnel" port VLAN mode. - In ovn-vsctl and vtep-ctl, record UUIDs in commands may now be abbreviated to 4 hex digits. - Userspace Datapath: * Added NAT support for userspace datapath. * Added FTP and TFTP support with NAT for userspace datapath. * Experimental NSH (Network Service Header) support in userspace datapath. - OVN: * New built-in DNS support. * IPAM for IPv4 can now exclude user-defined addresses from assignment. * IPAM can now assign IPv6 addresses. * Make the DHCPv4 router setting optional. * Gratuitous ARP for NAT addresses on a distributed logical router. * Allow ovn-controller SSL configuration to be obtained from vswitchd database. * ovn-trace now has basic support for tracing distributed firewalls. * In ovn-nbctl and ovn-sbctl, record UUIDs in commands may now be abbreviated to 4 hex digits. * "ovn-sbctl lflow-list" can now print OpenFlow flows that correspond to logical flows. * Now uses OVSDB RBAC support to reduce impact of compromised hypervisors. * Multiple chassis may now be specified for L3 gateways. When more than one chassis is specified, OVN will manage high availability for that gateway. * Add support for ACL logging. * ovn-northd now has native support for active-standby high availability. - Tracing with ofproto/trace now traces through recirculation. - OVSDB: * New support for role-based access control (see ovsdb-server(1)). - New commands 'stp/show' and 'rstp/show' (see ovs-vswitchd(8)). - OpenFlow: * All features required by OpenFlow 1.4 are now implemented, so ovs-vswitchd now enables OpenFlow 1.4 by default (in addition to OpenFlow 1.0 to 1.3). * Increased support for OpenFlow 1.6 (draft). * Bundles now support hashing by just nw_src or nw_dst. * The "learn" action now supports a "limit" option (see ovs-ofctl(8)). * The port status bit OFPPS_LIVE now reflects link aliveness. * OpenFlow 1.5 packet-out is now supported. * Support for OpenFlow 1.5 field packet_type and packet-type-aware pipeline (PTAP). * Added generic encap and decap actions (EXT-382). First supported use case is encap/decap for Ethernet. * Added NSH (Network Service Header) support in userspace Used generic encap and decap actions to implement encapsulation and decapsulation of NSH header. IETF NSH draft - https://datatracker.ietf.org/doc/draft-ietf-sfc-nsh/ * Conntrack state is only available to the processing path that follows the "recirc_table" argument of the ct() action. Starting in OVS 2.8, this state is now cleared for the current processing path whenever ct() is called. - Fedora Packaging: * OVN services are no longer restarted automatically after upgrade. * ovs-vswitchd and ovsdb-server run as non-root users by default. - Add --cleanup option to command 'ovs-appctl exit' (see ovs-vswitchd(8)). - L3 tunneling: * Use new tunnel port option "packet_type" to configure L2 vs. L3. * In conjunction with PTAP tunnel ports can handle a mix of L2 and L3 payload. * New vxlan tunnel extension "gpe" to support VXLAN-GPE tunnels. * New support for non-Ethernet (L3) payloads in GRE and VXLAN-GPE. - The BFD detection multiplier is now user-configurable. - Add experimental support for hardware offloading * HW offloading is disabled by default. * HW offloading is done through the TC interface. - IPv6 link local addresses are now supported on Linux. Use % to designate the scope device. v2.7.0 - 21 Feb 2017 --------------------- - Utilities and daemons that support SSL now allow protocols and ciphers to be configured with --ssl-protocols and --ssl-ciphers. - OVN: * QoS is now implemented via egress shaping rather than ingress policing. * DSCP marking is now supported, via the new northbound QoS table. * IPAM now supports fixed MAC addresses. * Support for source IP address based routing. * ovn-trace: - New --ovs option to also print OpenFlow flows. - put_dhcp_opts and put_dhcp_optsv6 actions may now be traced. * Support for managing SSL and remote connection configuration in northbound and southbound databases. * TCP connections to northbound and southbound databases are no longer enabled by default and must be explicitly configured. See documentation for ovn-sbctl/ovn-nbctl "set-connection" command or the ovn-ctl "--db-sb-create-insecure-remote" and "--db-nb-create-insecure-remote" command-line options for information regarding remote connection configuration. * New appctl "inject-pkt" command in ovn-controller that allows packets to be injected into the connected OVS instance. * Distributed logical routers may now be connected directly to logical switches with localnet ports, by specifying a "redirect-chassis" on the distributed gateway port of the logical router. NAT rules may be specified directly on the distributed logical router, and are handled either centrally on the "redirect-chassis", or in many cases are handled locally on the hypervisor where the corresponding logical port resides. Gratuitous ARP for NAT addresses on a distributed logical router is not yet supported, but will be added in a future version. - Fixed regression in table stats maintenance introduced in OVS 2.3.0, wherein the number of OpenFlow table hits and misses was not accurate. - OpenFlow: * OFPT_PACKET_OUT messages are now supported in bundles. * A new "selection_method=dp_hash" type for OpenFlow select group bucket selection that uses the datapath computed 5-tuple hash without making datapath flows match the 5-tuple fields, which is useful for more efficient load balancing, for example. This uses the Netronome extension to OpenFlow 1.5+ that allows control over the OpenFlow select groups selection method. See "selection_method" and related options in ovs-ofctl(8) for details. * The "sample" action now supports "ingress" and "egress" options. * The "ct" action now supports the TFTP ALG where support is available. * New actions "clone" and "ct_clear". * The "meter" action is now supported in the userspace datapath. - ovs-ofctl: * 'bundle' command now supports packet-out messages. * New syntax for 'ovs-ofctl packet-out' command, which uses the same string parser as the 'bundle' command. The old 'packet-out' syntax is deprecated and will be removed in a later OVS release. * New unixctl "ofctl/packet-out" command, which can be used to instruct a flow monitor to issue OpenFlow packet-out messages. - ovsdb-server: * Remote connections can now be made read-only (see ovsdb-server(1)). - Tunnels: * TLV mappings for protocols such as Geneve are now segregated on a per-OpenFlow bridge basis rather than globally. (The interface has not changed.) * Removed support for IPsec tunnels. - DPDK: * New option 'n_rxq_desc' and 'n_txq_desc' fields for DPDK interfaces which set the number of rx and tx descriptors to use for the given port. * Support for DPDK v16.11. * Support for rx checksum offload. Refer DPDK HOWTO for details. * Port Hotplug is now supported. * DPDK physical ports can now have arbitrary names. The PCI address of the device must be set using the 'dpdk-devargs' option. Compatibility with the old dpdk naming scheme is broken, and as such a device will not be available for use until a valid dpdk-devargs is specified. * Virtual DPDK Poll Mode Driver (vdev PMD) support. * Removed experimental tag. - Fedora packaging: * A package upgrade does not automatically restart OVS service. - ovs-vswitchd/ovs-vsctl: * Ports now have a "protected" flag. Protected ports can not forward frames to other protected ports. Unprotected ports can receive and forward frames to protected and other unprotected ports. - ovs-vsctl, ovn-nbctl, ovn-sbctl, vtep-ctl: * Database commands now accept integer ranges, e.g. "set port eth0 trunks=1-10" to enable trunking VLANs 1 to 10. v2.6.0 - 27 Sep 2016 --------------------- - First supported release of OVN. See ovn-architecture(7) for more details. - ovsdb-server: * New "monitor_cond" "monitor_cond_update" and "update2" extensions to RFC 7047. - OpenFlow: * OpenFlow 1.3+ bundles now expire after 10 seconds since the last time the bundle was either opened, modified, or closed. * OpenFlow 1.3 Extension 230, adding OpenFlow Bundles support, is now implemented. * OpenFlow 1.3+ bundles are now supported for group mods as well as flow mods and port mods. Both 'atomic' and 'ordered' bundle flags are supported for group mods as well as flow mods. * Internal OpenFlow rule representation for load and set-field actions is now much more memory efficient. For a complex flow table this can reduce rule memory consumption by 40%. * Bundles are now much more memory efficient than in OVS 2.5. Together with memory efficiency improvements in OpenFlow rule representation, the peak OVS resident memory use during a bundle commit for large complex set of flow mods can be only 25% of that in OVS 2.5 (4x lower). * OpenFlow 1.1+ OFPT_QUEUE_GET_CONFIG_REQUEST now supports OFPP_ANY. * OpenFlow 1.4+ OFPMP_QUEUE_DESC is now supported. * OpenFlow 1.4+ OFPT_TABLE_STATUS is now supported. * New property-based packet-in message format NXT_PACKET_IN2 with support for arbitrary user-provided data and for serializing flow table traversal into a continuation for later resumption. * New extension message NXT_SET_ASYNC_CONFIG2 to allow OpenFlow 1.4-like control over asynchronous messages in earlier versions of OpenFlow. * New OpenFlow extension NXM_NX_MPLS_TTL to provide access to MPLS TTL. * New output option, output(port=N,max_len=M), to allow truncating a packet to size M bytes when outputting to port N. * New command OFPGC_ADD_OR_MOD for OFPT_GROUP_MOD message that adds a new group or modifies an existing groups * The optional OpenFlow packet buffering feature is deprecated in this release, and will be removed in the next OVS release (2.7). After the change OVS always sends the 'buffer_id' as 0xffffffff in packet-in messages and will send an error response if any other value of this field is included in packet-out and flow mod sent by a controller. Controllers are already expected to work properly in cases where the switch can not buffer packets, so this change should not affect existing users. * New OpenFlow extension NXT_CT_FLUSH_ZONE to flush conntrack zones. - Improved OpenFlow version compatibility for actions: * New OpenFlow extension to support the "group" action in OpenFlow 1.0. * OpenFlow 1.0 "enqueue" action now properly translated to OpenFlow 1.1+. * OpenFlow 1.1 "mod_nw_ecn" and OpenFlow 1.1+ "mod_nw_ttl" actions now properly translated to OpenFlow 1.0. - ovs-ofctl: * queue-get-config command now allows a queue ID to be specified. * '--bundle' option can now be used with OpenFlow 1.3 and with group mods. * New "bundle" command allows executing a mixture of flow and group mods as a single atomic transaction. * New option "--color" to produce colorized output for some commands. * New option '--may-create' to use OFPGC_ADD_OR_MOD in mod-group command. - IPFIX: * New "sampling_port" option for "sample" action to allow sampling ingress and egress tunnel metadata with IPFIX. * New ovs-ofctl commands "dump-ipfix-bridge" and "dump-ipfix-flow" to dump bridge IPFIX statistics and flow based IPFIX statistics. * New setting other-config:virtual_obs_id to add an arbitrary string to IPFIX records. - Linux: * OVS Linux datapath now implements Conntrack NAT action with all supported Linux kernels. * Support for truncate action. * New QoS type "linux-noop" that prevents Open vSwitch from trying to manage QoS for a given port (useful when other software manages QoS). - DPDK: * New option "n_rxq" for PMD interfaces. Old 'other_config:n-dpdk-rxqs' is no longer supported. Not supported by vHost interfaces. For them number of rx and tx queues is applied from connected virtio device. * New 'other_config:pmd-rxq-affinity' field for PMD interfaces, that allows to pin port's rx queues to desired cores. * New appctl command 'dpif-netdev/pmd-rxq-show' to check the port/rxq assignment. * Type of log messages from PMD threads changed from INFO to DBG. * QoS functionality with sample egress-policer implementation. * The mechanism for configuring DPDK has changed to use database * Sensible defaults have been introduced for many of the required configuration options * DB entries have been added for many of the DPDK EAL command line arguments. Additional arguments can be passed via the dpdk-extra entry. * Add ingress policing functionality. * PMD threads servicing vHost User ports can now come from the NUMA node that device memory is located on if CONFIG_RTE_LIBRTE_VHOST_NUMA is enabled in DPDK. * Basic connection tracking for the userspace datapath (no ALG, fragmentation or NAT support yet) * Support for DPDK 16.07 * Optional support for DPDK pdump enabled. * Jumbo frame support * Remove dpdkvhostcuse port type. * OVS client mode for vHost and vHost reconnect (Requires QEMU 2.7) * 'dpdkvhostuserclient' port type. - Increase number of registers to 16. - ovs-benchmark: This utility has been removed due to lack of use and bitrot. - ovs-appctl: * New "vlog/close" command. - ovs-ctl: * Added the ability to selectively start the forwarding and database functions (ovs-vswitchd and ovsdb-server, respectively). - ovsdb-server: * Remove max number of sessions limit, to enable connection scaling testing. - python: * Added support for Python 3.4+ in addition to existing support for 2.7+. - SELinux: * Introduced SELinux policy package. - Datapath Linux kernel compatibility. * Dropped support for kernel older than 3.10. * Removed VLAN splinters feature. * Datapath supports kernel upto 4.7. - Tunnels: * Flow based tunnel match and action can be used for IPv6 address using tun_ipv6_src, tun_ipv6_dst fields. * Added support for IPv6 tunnels, for details checkout FAQ. * Deprecated support for IPsec tunnels ports. - A wrapper script, 'ovs-tcpdump', to easily port-mirror an OVS port and watch with tcpdump - Introduce --no-self-confinement flag that allows daemons to work with sockets outside their run directory. - ovs-pki: Changed message digest algorithm from SHA-1 to SHA-512 because SHA-1 is no longer secure and some operating systems have started to disable it in OpenSSL. - Add 'mtu_request' column to the Interface table. It can be used to configure the MTU of the ports. Known issues: - Using openvswitch module in conjunction with upstream Linux tunnels: * When using the openvswitch module distributed with OVS against kernel versions 4.4 to 4.6, the openvswitch module cannot be loaded or used at the same time as "ip_gre". - Conntrack FTP ALGs: When using the openvswitch module distributed with OVS, particular Linux distribution kernels versions may provide diminished functionality. This typically affects active FTP data connections when using "actions=ct(alg=ftp),..." in flow tables. Specifically: * Centos 7.1 kernels (3.10.0-2xx) kernels are unable to correctly set up expectations for FTP data connections in multiple zones, eg "actions=ct(zone=1,alg=ftp),ct(zone=2,alg=ftp),...". Executing the "ct" action for subsequent data connections may fail to determine that the data connection is "related" to an existing connection. * Centos 7.2 kernels (3.10.0-3xx) kernels may not establish FTP ALG state correctly for NATed connections. As a result, flows that perform NAT, eg "actions=ct(nat,ftp=alg,table=1),..." may fail to NAT the packet, and will populate the "ct_state=inv" bit in the flow. v2.5.0 - 26 Feb 2016 --------------------- - Dropped support for Python older than version 2.7. As a consequence, using Open vSwitch 2.5 or later on XenServer 6.5 or earlier (which have Python 2.4) requires first installing Python 2.7. - OpenFlow: * Group chaining (where one OpenFlow group triggers another) is now supported. * OpenFlow 1.4+ "importance" is now considered for flow eviction. * OpenFlow 1.4+ OFPTC_EVICTION is now implemented. * OpenFlow 1.4+ OFPTC_VACANCY_EVENTS is now implemented. * OpenFlow 1.4+ OFPMP_TABLE_DESC is now implemented. * Allow modifying the ICMPv4/ICMPv6 type and code fields. * OpenFlow 1.4+ OFPT_SET_ASYNC_CONFIG and OFPT_GET_ASYNC_CONFIG are now implemented. - ovs-ofctl: * New "out_group" keyword for OpenFlow 1.1+ matching on output group. - Tunnels: * Geneve tunnels can now match and set options and the OAM bit. * The nonstandard GRE64 tunnel extension has been dropped. - Support Multicast Listener Discovery (MLDv1 and MLDv2). - Add 'symmetric_l3l4' and 'symmetric_l3l4+udp' hash functions. - sFlow agent now reports tunnel and MPLS structures. - New 'check-system-userspace', 'check-kmod' and 'check-kernel' Makefile targets to run a new system testsuite. These tests can be run inside a Vagrant box. See INSTALL.md for details - Mark --syslog-target argument as deprecated. It will be removed in the next OVS release. - Added --user option to all daemons - Add support for connection tracking through the new "ct" action and "ct_state"/"ct_zone"/"ct_mark"/"ct_label" match fields. Only available on Linux kernels with the connection tracking module loaded. - Add experimental version of OVN. OVN, the Open Virtual Network, is a system to support virtual network abstraction. OVN complements the existing capabilities of OVS to add native support for virtual network abstractions, such as virtual L2 and L3 overlays and security groups. - RHEL packaging: * DPDK ports may now be created via network scripts (see README.RHEL). - DPDK: * Requires DPDK 2.2 * Added multiqueue support to vhost-user * Note: QEMU 2.5+ required for multiqueue support v2.4.0 - 20 Aug 2015 --------------------- - Flow table modifications are now atomic, meaning that each packet now sees a coherent version of the OpenFlow pipeline. For example, if a controller removes all flows with a single OpenFlow "flow_mod", no packet sees an intermediate version of the OpenFlow pipeline where only some of the flows have been deleted. - Added support for SFQ, FQ_CoDel and CoDel qdiscs. - Add bash command-line completion support for ovs-vsctl Please check utilities/ovs-command-compgen.INSTALL.md for how to use. - The MAC learning feature now includes per-port fairness to mitigate MAC flooding attacks. - New support for a "conjunctive match" OpenFlow extension, which allows constructing OpenFlow matches of the form "field1 in {a,b,c...} AND field2 in {d,e,f...}" and generalizations. For details, see documentation for the "conjunction" action in ovs-ofctl(8). - Add bash command-line completion support for ovs-appctl/ovs-dpctl/ ovs-ofctl/ovsdb-tool commands. Please check utilities/ovs-command-compgen.INSTALL.md for how to use. - The "learn" action supports a new flag "delete_learned" that causes the learned flows to be deleted when the flow with the "learn" action is deleted. - Basic support for the Geneve tunneling protocol. It is not yet possible to generate or match options. This is planned for a future release. The protocol is documented at http://tools.ietf.org/html/draft-gross-geneve-00 - The OVS database now reports controller rate limiting statistics. - sflow now exports information about LACP-based bonds, port names, and OpenFlow port numbers, as well as datapath performance counters. - ovs-dpctl functionality is now available for datapaths integrated into ovs-vswitchd, via ovs-appctl. Some existing ovs-appctl commands are now redundant and will be removed in a future release. See ovs-vswitchd(8) for details. - OpenFlow: * OpenFlow 1.4 bundles are now supported for flow mods and port mods. For flow mods, both 'atomic' and 'ordered' bundle flags are trivially supported, as all bundled messages are executed in the order they were added and all flow table modifications are now atomic to the datapath. Port mods may not appear in atomic bundles, as port status modifications are not atomic. * IPv6 flow label and neighbor discovery fields are now modifiable. * OpenFlow 1.5 extended registers are now supported. * The OpenFlow 1.5 actset_output field is now supported. * OpenFlow 1.5 Copy-Field action is now supported. * OpenFlow 1.5 masked Set-Field action is now supported. * OpenFlow 1.3+ table features requests are now supported (read-only). * Nicira extension "move" actions may now be included in action sets. * "resubmit" actions may now be included in action sets. The resubmit is executed last, and only if the action set has no "output" or "group" action. * OpenFlow 1.4+ flow "importance" is now maintained in the flow table. * A new Netronome extension to OpenFlow 1.5+ allows control over the fields hashed for OpenFlow select groups. See "selection_method" and related options in ovs-ofctl(8) for details. - ovs-ofctl has a new '--bundle' option that makes the flow mod commands ('add-flow', 'add-flows', 'mod-flows', 'del-flows', and 'replace-flows') use an OpenFlow 1.4 bundle to operate the modifications as a single atomic transaction. If any of the flow mods in a transaction fail, none of them are executed. All flow mods in a bundle appear to datapath lookups simultaneously. - ovs-ofctl 'add-flow' and 'add-flows' commands now accept arbitrary flow mods as an input by allowing the flow specification to start with an explicit 'add', 'modify', 'modify_strict', 'delete', or 'delete_strict' keyword. A missing keyword is treated as 'add', so this is fully backwards compatible. With the new '--bundle' option all the flow mods are executed as a single atomic transaction using an OpenFlow 1.4 bundle. - ovs-pki: Changed message digest algorithm from MD5 to SHA-1 because MD5 is no longer secure and some operating systems have started to disable it in OpenSSL. - ovsdb-server: New OVSDB protocol extension allows inequality tests on "optional scalar" columns. See ovsdb-server(1) for details. - ovs-vsctl now permits immutable columns in a new row to be modified in the same transaction that creates the row. - test-controller has been renamed ovs-testcontroller at request of users who find it useful for testing basic OpenFlow setups. It is still not a necessary or desirable part of most Open vSwitch deployments. - Support for travis-ci.org based continuous integration builds has been added. Build failures are reported to build@openvswitch.org. See INSTALL.md file for additional details. - Support for the Rapid Spanning Tree Protocol (IEEE 802.1D-2004). The implementation has been tested successfully against the Ixia Automated Network Validation Library (ANVL). - Stats are no longer updated on fake bond interface. - Keep active bond slave selection across OVS restart. - A simple wrapper script, 'ovs-docker', to integrate OVS with Docker containers. If and when there is a native integration of Open vSwitch with Docker, the wrapper script will be retired. - Added support for DPDK Tunneling. VXLAN, GRE, and Geneve are supported protocols. This is generic tunneling mechanism for userspace datapath. - Support for multicast snooping (IGMPv1, IGMPv2 and IGMPv3) - Support for Linux kernels up to 4.0.x - The documentation now use the term 'destination' to mean one of syslog, console or file for vlog logging instead of the previously used term 'facility'. - Support for VXLAN Group Policy extension - Initial support for the IETF Auto-Attach SPBM draft standard. This contains rudimentary support for the LLDP protocol as needed for Auto-Attach. - The default OpenFlow and OVSDB ports are now the IANA-assigned numbers. OpenFlow is 6653 and OVSDB is 6640. - Support for DPDK vHost. - Support for outer UDP checksums in Geneve and VXLAN. - The kernel vports with dependencies are no longer part of the overall openvswitch.ko but built and loaded automatically as individual kernel modules (vport-*.ko). - Support for STT tunneling. - ovs-sim: New developer tool for simulating multiple OVS instances. See ovs-sim(1) for more information. - Support to configure method (--syslog-method argument) that determines how daemons will talk with syslog. - Support for "ovs-appctl vlog/list-pattern" command that lets to query logging message format for each destination. v2.3.0 - 14 Aug 2014 --------------------- - OpenFlow 1.1, 1.2, and 1.3 are now enabled by default in ovs-vswitchd. - Linux kernel datapath now has an exact match cache optimizing the flow matching process. - Datapath flows now have partially wildcarded tranport port field matches. This reduces userspace upcalls, but increases the number of different masks in the datapath. The kernel datapath exact match cache removes the overhead of matching the incoming packets with the larger number of masks, but when paired with an older kernel module, some workloads may perform worse with the new userspace. - Compatibility with autoconf 2.63 (previously >=2.64) v2.2.0 - Internal Release --------------------- - Internal ports are no longer brought up by default, because it should be an administrator task to bring up devices as they are configured properly. - ovs-vsctl now reports when ovs-vswitchd fails to create a new port or bridge. - Port creation and configuration errors are now stored in a new error column of the Interface table and included in 'ovs-vsctl show'. - The "ovsdbmonitor" graphical tool has been removed, because it was poorly maintained and not widely used. - New "check-ryu" Makefile target for running Ryu tests for OpenFlow controllers against Open vSwitch. See INSTALL.md for details. - Added IPFIX support for SCTP flows and templates for ICMPv4/v6 flows. - Upon the receipt of a SIGHUP signal, ovs-vswitchd no longer reopens its log file (it will terminate instead). Please use 'ovs-appctl vlog/reopen' instead. - Support for Linux kernels up to 3.14. From Kernel 3.12 onwards OVS uses tunnel API for GRE and VXLAN. - Added DPDK support. - Added support for custom vlog patterns in Python v2.1.0 - 19 Mar 2014 --------------------- - Address prefix tracking support for flow tables. New columns "prefixes" in OVS-DB table "Flow_Table" controls which packet header fields are used for address prefix tracking. Prefix tracking allows the classifier to skip rules with longer than necessary prefixes, resulting in better wildcarding for datapath flows. Default configuration is to not use any fields for prefix tracking. However, if any flow tables contain both exact matches and masked matches for IP address fields, OVS performance may be increased by using this feature. * As of now, the fields for which prefix lookup can be enabled are: 'tun_id', 'tun_src', 'tun_dst', 'nw_src', 'nw_dst' (or aliases 'ip_src' and 'ip_dst'), 'ipv6_src', and 'ipv6_dst'. (Using this feature for 'tun_id' would only make sense if the tunnel IDs have prefix structure similar to IP addresses.) * There is a maximum number of fields that can be enabled for any one flow table. Currently this limit is 3. * Examples: $ ovs-vsctl set Bridge br0 flow_tables:0=@N1 -- \ --id=@N1 create Flow_Table name=table0 $ ovs-vsctl set Bridge br0 flow_tables:1=@N1 -- \ --id=@N1 create Flow_Table name=table1 $ ovs-vsctl set Flow_Table table0 prefixes=ip_dst,ip_src $ ovs-vsctl set Flow_Table table1 prefixes=[] - TCP flags matching: OVS now supports matching of TCP flags. This has an adverse performance impact when using OVS userspace 1.10 or older (no megaflows support) together with the new OVS kernel module. It is recommended that the kernel and userspace modules both are upgraded at the same time. - The default OpenFlow and OVSDB ports will change to IANA-assigned numbers in a future release. Consider updating your installations to specify port numbers instead of using the defaults. - OpenFlow: * The OpenFlow 1.1+ "Write-Actions" instruction is now supported. * OVS limits the OpenFlow port numbers it assigns to port 32767 and below, leaving port numbers above that range free for assignment by the controller. * ovs-vswitchd now honors changes to the "ofport_request" column in the Interface table by changing the port's OpenFlow port number. * The Open vSwitch software switch now supports OpenFlow groups. - ovs-vswitchd.conf.db.5 man page will contain graphviz/dot diagram only if graphviz package was installed at the build time. - Support for Linux kernels up to 3.11 - ovs-dpctl: The "show" command also displays mega flow mask stats. - ovs-ofctl: * New command "ofp-parse-pcap" to dump OpenFlow from PCAP files. - ovs-controller has been renamed test-controller. It is no longer packaged or installed by default, because too many users assumed incorrectly that ovs-controller was a necessary or desirable part of an Open vSwitch deployment. - Added vlog option to export to a UDP syslog sink. - ovsdb-client: * The "monitor" command can now monitor all tables in a database, instead of being limited to a single table. - The flow-eviction-threshold has been replaced by the flow-limit which is a hard limit on the number of flows in the datapath. It defaults to 200,000 flows. OVS automatically adjusts this number depending on network conditions. - Added IPv6 support for active and passive socket communications. v2.0.0 - 15 Oct 2013 --------------------- - The ovs-vswitchd process is no longer single-threaded. Multiple threads are now used to handle flow set up and asynchronous logging. - OpenFlow: * Experimental support for OpenFlow 1.1 (in addition to 1.2 and 1.3, which had experimental support in 1.10). * Experimental protocol support for OpenFlow 1.1+ groups. This does not yet include an implementation in the Open vSwitch software switch. * Experimental protocol support for OpenFlow 1.2+ meters. This does not yet include an implementation in the Open vSwitch software switch. * New support for matching outer source and destination IP address of tunneled packets, for tunnel ports configured with the newly added "remote_ip=flow" and "local_ip=flow" options. * Support for matching on metadata 'pkt_mark' for interacting with other system components. On Linux this corresponds to the skb mark. * Support matching, rewriting SCTP ports - The Interface table in the database has a new "ifindex" column to report the interface's OS-assigned ifindex. - New "check-oftest" Makefile target for running OFTest against Open vSwitch. See README-OFTest for details. - The flow eviction threshold has been moved to the Open_vSwitch table. - Database names are now mandatory when specifying ovsdb-server options through database paths (e.g. Private key option with the database name should look like "--private-key=db:Open_vSwitch,SSL,private_key"). - Added ovs-dev.py, a utility script helpful for Open vSwitch developers. - Support for Linux kernels up to 3.10 - ovs-ofctl: * New "ofp-parse" for printing OpenFlow messages read from a file. * New commands for OpenFlow 1.1+ groups. - Added configurable flow caching support to IPFIX exporter. - Dropped support for Linux pre-2.6.32. - Log file timestamps and ovsdb commit timestamps are now reported with millisecond resolution. (Previous versions only reported whole seconds.) v1.11.0 - 28 Aug 2013 --------------------- - Support for megaflows, which allows wildcarding in the kernel (and any dpif implementation that supports wildcards). Depending on the flow table and switch configuration, flow set up rates are close to the Linux bridge. - The "tutorial" directory contains a new tutorial for some advanced Open vSwitch features. - Stable bond mode has been removed. - The autopath action has been removed. - New support for the data encapsulation format of the LISP tunnel protocol (RFC 6830). An external control plane or manual flow setup is required for EID-to-RLOC mapping. - OpenFlow: * The "dec_mpls_ttl" and "set_mpls_ttl" actions from OpenFlow 1.1 and later are now implemented. * New "stack" extension for use in actions, to push and pop from NXM fields. * The "load" and "set_field" actions can now modify the "in_port". (This allows one to enable output to a flow's input port by setting the in_port to some unused value, such as OFPP_NONE.) - ovs-dpctl: * New debugging commands "add-flow", "mod-flow", "del-flow". * "dump-flows" now has a -m option to increase output verbosity. - In dpif-based bridges, cache action translations, which can improve flow set up performance by 80% with a complicated flow table. - New syslog format, prefixed with "ovs|", to be easier to filter. - RHEL: Removes the default firewall rule that allowed GRE traffic to pass through. Any users that relied on this automatic firewall hole will have to manually configure it. The ovs-ctl(8) manpage documents the "enable-protocol" command that can be used as an alternative. - New CFM demand mode which uses data traffic to indicate interface liveness. v1.10.0 - 01 May 2013 --------------------- - Bridge compatibility support has been removed. Any uses that rely on ovs-brcompatd will have to stick with Open vSwitch 1.9.x or adapt to native Open vSwitch support (e.g. use ovs-vsctl instead of brctl). - The maximum size of the MAC learning table is now configurable. - With the Linux datapath, packets for new flows are now queued separately on a per-port basis, so it should no longer be possible for a large number of new flows arriving on one port to prevent new flows from being processed on other ports. - ovs-vsctl: * Previously ovs-vsctl would retry connecting to the database forever, causing it to hang if ovsdb-server was not running. Now, ovs-vsctl only tries once by default (use --retry to try forever). This change means that you may want to remove uses of --timeout to avoid hangs in ovs-vsctl calls. * Many "ovs-vsctl" database commands now accept an --if-exists option. Please refer to the ovs-vsctl manpage for details. - OpenFlow: - Experimental support for newer versions of OpenFlow. See the "What versions of OpenFlow does Open vSwitch support?" question in the FAQ for more details. - The OpenFlow "dp_desc" may now be configured by setting the value of other-config:dp-desc in the Bridge table. - It is possible to request the OpenFlow port number with the "ofport_request" column in the Interface table. - The NXM flow_removed message now reports the OpenFlow table ID from which the flow was removed. - Tunneling: - New support for the VXLAN tunnel protocol (see the IETF draft here: http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-03). - Tunneling requires the version of the kernel module paired with Open vSwitch 1.9.0 or later. - Inheritance of the Don't Fragment bit in IP tunnels (df_inherit) is no longer supported. - Path MTU discovery is no longer supported. - CAPWAP tunneling support removed. - Tunnels with multicast destination ports are no longer supported. - ovs-dpctl: - The "dump-flows" and "del-flows" no longer require an argument if only one datapath exists. - ovs-appctl: - New "vlog/disable-rate-limit" and "vlog/enable-rate-limit" commands available allow control over logging rate limits. - New "dpif/dump-dps", "dpif/show", and "dpif/dump-flows" command that mimic the equivalent ovs-dpctl commands. - The ofproto library is now responsible for assigning OpenFlow port numbers. An ofproto implementation should assign them when port_construct() is called. - All dpif-based bridges of a particular type share a common datapath called "ovs-", e.g. "ovs-system". The ovs-dpctl commands will now return information on that shared datapath. To get the equivalent bridge-specific information, use the new "ovs-appctl dpif/*" commands. - Backward-incompatible changes: - Earlier Open vSwitch versions treated ANY as a wildcard in flow syntax. OpenFlow 1.1 adds a port named ANY, which introduces a conflict. ANY was rarely used in flow syntax, so we chose to retire that meaning of ANY in favor of the OpenFlow 1.1 meaning. - Patch ports no longer require kernel support, so they now work with FreeBSD and the kernel module built into Linux 3.3 and later. - New "sample" action. v1.9.0 - 26 Feb 2013 ------------------------ - Datapath: - Support for ipv6 set action. - SKB mark matching and setting. - support for Linux kernels up to 3.8 - FreeBSD is now a supported platform, thanks to code contributions from Gaetano Catalli, Ed Maste, and Giuseppe Lettieri. - ovs-bugtool: New --ovs option to report only OVS related information. - New %t and %T log escapes to identify the subprogram within a cooperating group of processes or threads that emitted a log message. The default log patterns now include this information. - OpenFlow: - Allow bitwise masking for SHA and THA fields in ARP, SLL and TLL fields in IPv6 neighbor discovery messages, and IPv6 flow label. - Adds support for writing to the metadata field for a flow. - Tunneling: - The tunneling code no longer assumes input and output keys are symmetric. If they are not, PMTUD needs to be disabled for tunneling to work. Note this only applies to flow-based keys. - New support for a nonstandard form of GRE that supports a 64-bit key. - Tunnel Path MTU Discovery default value was set to 'disabled'. This feature is deprecated and will be removed soon. - Tunnel header caching removed. - ovs-ofctl: - Commands and actions that accept port numbers now also accept keywords that represent those ports (such as LOCAL, NONE, and ALL). This is also the recommended way to specify these ports, for compatibility with OpenFlow 1.1 and later (which use the OpenFlow 1.0 numbers for these ports for different purposes). - ovs-dpctl: - Support requesting the port number with the "port_no" option in the "add-if" command. - ovs-pki: The "online PKI" features have been removed, along with the ovs-pki-cgi program that facilitated it, because of some alarmist insecurity claims. We do not believe that these claims are true, but because we do not know of any users for this feature it seems better on balance to remove it. (The ovs-pki-cgi program was not included in distribution packaging.) - ovsdb-server now enforces the immutability of immutable columns. This was not enforced in earlier versions due to an oversight. - The following features are now deprecated. They will be removed no earlier than February 2013. Please email dev@openvswitch.org with concerns. - Bridge compatibility. - Stable bond mode. - The autopath action. - Interface type "null". - Numeric values for reserved ports (see "ovs-ofctl" note above). - Tunnel Path MTU Discovery. - CAPWAP tunnel support. - The data in the RARP packets can now be matched in the same way as the data in ARP packets. v1.8.0 - 26 Feb 2013 ------------------------ *** Internal only release *** - New FAQ. Please send updates and additions! - Authors of controllers, please read the new section titled "Action Reproduction" in DESIGN, which describes an Open vSwitch change in behavior in corner cases that may affect some controllers. - ovs-l3ping: - A new test utility that can create L3 tunnel between two Open vSwitches and detect connectivity issues. - ovs-ofctl: - New --sort and --rsort options for "dump-flows" command. - "mod-port" command can now control all OpenFlow config flags. - OpenFlow: - Allow general bitwise masking for IPv4 and IPv6 addresses in IPv4, IPv6, and ARP packets. (Previously, only CIDR masks were allowed.) - Allow support for arbitrary Ethernet masks. (Previously, only the multicast bit in the destination address could be individually masked.) - New field OXM_OF_METADATA, to align with OpenFlow 1.1. - The OFPST_QUEUE request now reports an error if a specified port or queue does not exist, or for requests for a specific queue on all ports, if the specified queue does not exist on any port. (Previous versions generally reported an empty set of results.) - New "flow monitor" feature to allow controllers to be notified of flow table changes as they happen. - Additional protocols are not mirrored and dropped when forward-bpdu is false. For a full list, see the ovs-vswitchd.conf.db man page. - Open vSwitch now sends RARP packets in situations where it previously sent a custom protocol, making it consistent with behavior of QEMU and VMware. - All Open vSwitch programs and log files now show timestamps in UTC, instead the local timezone, by default. v1.7.0 - 30 Jul 2012 ------------------------ - kernel modules are renamed. openvswitch_mod.ko is now openvswitch.ko and brcompat_mod.ko is now brcompat.ko. - Increased the number of NXM registers to 8. - Added ability to configure DSCP setting for manager and controller connections. By default, these connections have a DSCP value of Internetwork Control (0xc0). - Added the granular link health statistics, 'cfm_health', to an interface. - OpenFlow: - Added support to mask nd_target for ICMPv6 neighbor discovery flows. - Added support for OpenFlow 1.3 port description (OFPMP_PORT_DESC) multipart messages. - ovs-ofctl: - Added the "dump-ports-desc" command to retrieve port information using the new port description multipart messages. - ovs-test: - Added support for spawning ovs-test server from the client. - Now ovs-test is able to automatically create test bridges and ports. - "ovs-dpctl dump-flows" now prints observed TCP flags in TCP flows. - Tripled flow setup performance. - The "coverage/log" command previously available through ovs-appctl has been replaced by "coverage/show". The new command replies with coverage counter values, instead of logging them. v1.6.1 - 25 Jun 2012 ------------------------ - Allow OFPP_CONTROLLER as the in_port for packet-out messages. v1.6.0 - 24 Feb 2012 ------------------------ *** Internal only release *** - bonding - LACP bonds no longer fall back to balance-slb when negotiations fail. Instead they drop traffic. - The default bond_mode changed from SLB to active-backup, to protect unsuspecting users from the significant risks of SLB bonds (which are documented in vswitchd/INTERNALS). - Load balancing can be disabled by setting the bond-rebalance-interval to zero. - OpenFlow: - Added support for bitwise matching on TCP and UDP ports. See ovs-ofctl(8) for more information. - NXM flow dumps now include times elapsed toward idle and hard timeouts. - Added an OpenFlow extension NXT_SET_ASYNC_CONFIG that allows controllers more precise control over which OpenFlow messages they receive asynchronously. - New "fin_timeout" action. - Added "fin_timeout" support to "learn" action. - New Nicira action NXAST_CONTROLLER that offers additional features over output to OFPP_CONTROLLER. - When QoS settings for an interface do not configure a default queue (queue 0), Open vSwitch now uses a default configuration for that queue, instead of dropping all packets as in previous versions. - Logging: - Logging to console and file will have UTC timestamp as a default for all the daemons. An example of the default format is 2012-01-27T16:35:17Z. ovs-appctl can be used to change the default format as before. - The syntax of commands and options to set log levels was simplified, to make it easier to remember. - New support for limiting the number of flows in an OpenFlow flow table, with configurable policy for evicting flows upon overflow. See the Flow_Table table in ovs-vswitch.conf.db(5) for more information. - New "enable-async-messages" column in the Controller table. If set to false, OpenFlow connections to the controller will initially have all asynchronous messages disabled, overriding normal OpenFlow behavior. - ofproto-provider interface: - "struct rule" has a new member "used" that ofproto implementations should maintain by updating with ofproto_rule_update_used(). - ovsdb-client: - The new option --timestamp causes the "monitor" command to print a timestamp with every update. - CFM module CCM broadcasts can now be tagged with an 802.1p priority. v1.5.0 - 01 Jun 2012 ------------------------ - OpenFlow: - Added support for querying, modifying, and deleting flows based on flow cookie when using NXM. - Added new NXM_PACKET_IN format. - Added new NXAST_DEC_TTL action. - ovs-ofctl: - Added daemonization support to the monitor and snoop commands. - ovs-vsctl: - The "find" command supports new set relational operators {=}, {!=}, {<}, {>}, {<=}, and {>=}. - ovsdb-tool now uses the typical database and schema installation directories as defaults. - The default MAC learning timeout has been increased from 60 seconds to 300 seconds. The MAC learning timeout is now configurable. v1.4.0 - 30 Jan 2012 ------------------------ - Compatible with Open vSwitch kernel module included in Linux 3.3. - New "VLAN splinters" feature to work around buggy device drivers in old Linux versions. (This feature is deprecated. When broken device drivers are no longer in widespread use, we will delete this feature.) See ovs-vswitchd.conf.db(5) for more information. - OpenFlow: - Added ability to match on IPv6 flow label through NXM. - Added ability to match on ECN bits in IPv4 and IPv6 through NXM. - Added ability to match on TTL in IPv4 and IPv6 through NXM. - Added ability to modify ECN bits in IPv4. - Added ability to modify TTL in IPv4. - ovs-vswitchd: - Don't require the "normal" action to use mirrors. Traffic will now be properly mirrored for any flows, regardless of their actions. - Track packet and byte statistics sent on mirrors. - The sFlow implementation can now usually infer the correct agent device instead of having to be told explicitly. - ovs-appctl: - New "fdb/flush" command to flush bridge's MAC learning table. - ovs-test: - A new distributed testing tool that allows one to diagnose performance and connectivity issues. This tool currently is not included in RH or Xen packages. - RHEL packaging now supports integration with Red Hat network scripts. - bonding: - Post 1.4.*, OVS will be changing the default bond mode from balance-slb to active-backup. SLB bonds carry significant risks with them (documented vswitchd/INTERNALS) which we want to prevent unsuspecting users from running into. Users are advised to update any scripts or configuration which may be negatively impacted by explicitly setting the bond mode which they want to use. v1.3.0 - 09 Dec 2011 ------------------------ - OpenFlow: - Added an OpenFlow extension which allows the "output" action to accept NXM fields. - Added an OpenFlow extension for flexible learning. - Bumped number of NXM registers from four to five. - ovs-appctl: - New "version" command to determine version of running daemon. - If no argument is provided for "cfm/show", displays detailed information about all interfaces with CFM enabled. - If no argument is provided for "lacp/show", displays detailed information about all ports with LACP enabled. - ovs-dpctl: - New "set-if" command to modify a datapath port's configuration. - ovs-vswitchd: - The software switch now supports 255 OpenFlow tables, instead of just one. By default, only table 0 is consulted, but the new NXAST_RESUBMIT_TABLE action can look up in additional tables. Tables 128 and above are reserved for use by the switch itself; please use only tables 0 through 127. - Add support for 802.1D spanning tree (STP). - Fragment handling extensions: - New OFPC_FRAG_NX_MATCH fragment handling mode, in which L4 fields are made available for matching in fragments with offset 0. - New NXM_NX_IP_FRAG match field for matching IP fragments (usable via "ip_frag" in ovs-ofctl). - New ovs-ofctl "get-frags" and "set-frags" commands to get and set fragment handling policy. - CAPWAP tunneling now supports an extension to transport a 64-bit key. By default it remains compatible with the old version and other standards-based implementations. - Flow setups are now processed in a round-robin manner across ports to prevent any single client from monopolizing the CPU and conducting a denial of service attack. - Added support for native VLAN tagging. A new "vlan_mode" parameter can be set for "port". Possible values: "access", "trunk", "native-tagged" and "native-untagged". - test-openflowd has been removed. Please use ovs-vswitchd instead. v1.2.0 - 03 Aug 2011 ------------------------ - New "ofproto" abstraction layer to ease porting to hardware switching ASICs. - Packaging for Red Hat Enterprise Linux 5.6 and 6.0. - Datapath support for Linux kernels up to 3.0. - OpenFlow: - New "bundle" and "bundle_load" action extensions. - Database: - Implement table unique constraints. - Support cooperative locking between callers. - ovs-dpctl: - New "-s" option for "show" command prints packet and byte counters for each port. - ovs-ofctl: - New "--readd" option for "replace-flows". - ovs-vsctl: - New "show" command to print an overview of configuration. - New "comment" command to add remark that explains intentions. - ovs-brcompatd has been rewritten to fix long-standing bugs. - ovs-openflowd has been renamed test-openflowd and moved into the tests directory. Its presence confused too many users. Please use ovs-vswitchd instead. - New ovs-benchmark utility to test flow setup performance. - A new log level "off" has been added. Configuring a log facility "off" prevents any messages from being logged to it. Previously, "emer" was effectively "off" because no messages were ever logged at level "emer". Now, errors that cause a process to exit are logged at "emer" level. - "configure" option --with-l26 has been renamed --with-linux, and --with-l26-source has been renamed --with-linux-source. The old names will be removed after the next release, so please update your scripts. - The "-2.6" suffix has been dropped from the datapath/linux-2.6 and datapath/linux-2.6/compat-2.6 directories. - Feature removals: - Dropped support for "tun_id_from_cookie" OpenFlow extension. Please use the extensible match extensions instead. - Removed the Maintenance_Point and Monitor tables in an effort to simplify 802.1ag configuration. - Performance and scalability improvements - Bug fixes v1.1.0 - 05 Apr 2011 ------------------------ - Ability to define policies over IPv6 - LACP - 802.1ag CCM - Support for extensible match extensions to OpenFlow - QoS: - Support for HFSC qdisc. - Queue used by in-band control can now be configured. - Kernel: - Kernel<->userspace interface has been reworked and should be close to a stable ABI now. - "Port group" concept has been dropped. - GRE over IPSEC tunnels - Bonding: - New active backup bonding mode. - New L4 hashing support when LACP is enabled. - Source MAC hash now includes VLAN field also. - miimon support. - Greatly improved handling of large flow tables - ovs-dpctl: - "show" command now prints full vport configuration. - "dump-groups" command removed since kernel support for port groups was dropped. - ovs-vsctl: - New commands for working with the new Managers table. - "list" command enhanced with new formatting options and --columns option. - "get" command now accepts new --id option. - New "find" command. - ovs-ofctl: - New "queue-stats" command for printing queue stats. - New commands "replace-flows" and "diff-flows". - Commands to add and remove flows can now read from files. - New --flow-format option to enable or disable NXM. - New --more option to increase OpenFlow message verbosity. - Removed "tun-cookie" command, which is no longer useful. - ovs-controller enhancements for testing various features. - New ovs-vlan-test command for testing for Linux kernel driver VLAN bugs. New ovs-vlan-bug-workaround command for enabling and disabling a workaround for these driver bugs. - OpenFlow support: - "Resubmit" actions now update flow statistics. - New "register" extension for use in matching and actions, via NXM. - New "multipath" experimental action extension. - New support for matching multicast Ethernet frames, via NXM. - New extension for OpenFlow vendor error codes. - New extension to set the QoS output queue without actually sending to an output port. - Open vSwitch now reports a single flow table, instead of separate hash and wildcard tables. This better models the current implementation. - New experimental "note" action. - New "ofproto/trace" ovs-appctl command and associated utilities to ease debugging complex flow tables. - Database: - Schema documentation now includes an entity-relationship diagram. - The database is now garbage collected. In most tables, unreferenced rows will be deleted automatically. - Many tables now include statistics updated periodically by ovs-vswitchd or ovsdb-server. - Every table now has an "external-ids" column for use by OVS integrators. - There is no default controller anymore. Each bridge must have its controller individually specified. - The "fail-mode" is now a property of a Bridge instead of a Controller. - New versioning and checksum features. - New Managers table and manager_options column in Open_vSwitch table for specifying managers. The old "managers" column in the Open_vSwitch table has been removed. - Many "name" columns are now immutable. - Feature removals: - Dropped support for XenServer pre-5.6.100. - Dropped support for Linux pre-2.6.18. - Dropped controller discovery support. - Dropped "ovs-ofctl status" and the OpenFlow extension that it used. Statistics reporting in the database is a rough equivalent. - Dropped the "corekeeper" package (now separate, at http://openvswitch.org/cgi-bin/gitweb.cgi?p=corekeeper). - Performance and scalability improvements - Bug fixes v1.1.0pre2 - 13 Sep 2010 ------------------------ - Bug fixes v1.1.0pre1 - 31 Aug 2010 ------------------------ - OpenFlow 1.0 slicing (QoS) functionality - Python bindings for configuration database (no write support) - Performance and scalability improvements - Bug fixes v1.0.1 - 31 May 2010 -------------------- - New "patch" interface type - Bug fixes v1.0.0 - 15 May 2010 -------------------- - Configuration database with remote management - OpenFlow 1.0 - GRE tunneling - Support for XenServer 5.5 and 5.6 - Performance and scalability improvements - Bug fixes v0.99.2 - 18 Feb 2010 --------------------- - Bug fixes v0.99.1 - 25 Jan 2010 --------------------- - Add support for sFlow(R) - Make headers compatible with C++ - Bug fixes v0.99.0 - 14 Jan 2010 --------------------- - User-space forwarding engine - Bug fixes v0.90.7 - 29 Nov 2009 --------------------- - Add support for NetFlow active timeouts - Bug fixes v0.90.6 - 6 Oct 2009 -------------------- - Bug fixes v0.90.5 - 21 Sep 2009 --------------------- - Generalize in-band control to more diverse network setups - Bug fixes ovn-25.09.0~git20250813.23884f5/NOTICE000066400000000000000000000027151504532661100160560ustar00rootroot00000000000000This file is included in compliance with the Apache 2.0 license, available at http://www.apache.org/licenses/LICENSE-2.0.html Open vSwitch Copyright (c) 2007, 2008, 2009, 2010, 2011, 2013 Nicira, Inc. Open vSwitch BSD port Copyright (c) 2011 Gaetano Catalli Apache Portable Runtime Copyright 2008 The Apache Software Foundation. This product includes software developed by The Apache Software Foundation (http://www.apache.org/). Portions of this software were developed at the National Center for Supercomputing Applications (NCSA) at the University of Illinois at Urbana-Champaign. lib/ovs.tmac includes troff macros written by Eric S. Raymond and Werner Lemberg. m4/include_next.m4 and m4/absolute-header.m4 Copyright (C) 2006-2013 Free Software Foundation, Inc. Rapid Spanning Tree Protocol (RSTP) implementation Copyright (c) 2011-2014 M3S, Srl - Italy LLDP implementation Copyright (c) 2008, 2012 Vincent Bernat LLDP includes code used from the Net::CDP project based on the ISC license Copyright (c) 2014 Michael Chapman LLDP includes code used from the ladvd project based on the ISC license Copyright (c) 2008, 2009, 2010 Sten Spans Auto Attach implementation Copyright (c) 2014, 2015 WindRiver, Inc Copyright (c) 2014, 2015 Avaya, Inc TCP connection tracker from FreeBSD pf, BSD licensed Copyright (c) 2001 Daniel Hartmeier Copyright (c) 2002 - 2008 Henning Brauer Copyright (c) 2012 Gleb Smirnoff ovn-25.09.0~git20250813.23884f5/README.rst000066400000000000000000000101441504532661100166340ustar00rootroot00000000000000.. NOTE(stephenfin): If making changes to this file, ensure that the line numbers found in 'Documentation/intro/what-is-ovs' are kept up-to-date. === OVN === .. image:: https://github.com/ovn-org/ovn/actions/workflows/test.yml/badge.svg :target: https://github.com/ovn-org/ovn/actions/workflows/test.yml .. image:: https://github.com/ovn-org/ovn/actions/workflows/ovn-kubernetes.yml/badge.svg :target: https://github.com/ovn-org/ovn/actions/workflows/ovn-kubernetes.yml .. image:: https://github.com/ovn-org/ovn/actions/workflows/ovn-fake-multinode-tests.yml/badge.svg :target: https://github.com/ovn-org/ovn/actions/workflows/ovn-fake-multinode-tests.yml .. image:: https://api.cirrus-ci.com/github/ovn-org/ovn.svg :target: https://cirrus-ci.com/github/ovn-org/ovn .. image:: https://readthedocs.org/projects/ovn/badge/?version=latest :target: https://docs.ovn.org/en/latest/ .. image:: https://scan.coverity.com/projects/30371/badge.svg :target: https://scan.coverity.com/projects/open-virtual-network What is OVN? --------------------- OVN (Open Virtual Network) is a series of daemons that translates virtual network configuration into OpenFlow, and installs them into Open vSwitch. It is licensed under the open source Apache 2 license. OVN provides a higher-layer abstraction than Open vSwitch, working with logical routers and logical switches, rather than flows. OVN is intended to be used by cloud management software (CMS). For details about the architecture of OVN, see the ovn-architecture manpage. Some high-level features offered by OVN include: * Distributed virtual routers * Distributed logical switches * Access Control Lists * DHCP * DNS server Like Open vSwitch, OVN is written in platform-independent C. OVN runs entirely in userspace and therefore requires no kernel modules to be installed. Until recently, OVN code lived within the Open vSwitch codebase. OVN has recently been split into its own repo. There is much to do to complete this split entirely. See the TODO_SPLIT.rst file for a list of known tasks that need to be completed. What's here? ------------ The main components of this distribution are: - ovn-northd, a centralized daemon that translates northbound configuration from a CMS into logical flows for the southbound database. - ovn-controller, a daemon that runs on every hypervisor in the cluster. It translates the logical flows in the southbound database into OpenFlow for Open vSwitch. It also handles certain traffic, such as DHCP and DNS. - ovn-nbctl, a tool for interfacing with the northbound database. - ovn-sbctl, a tool for interfacing with the southbound database. - ovn-trace, a debugging utility that allows for tracing of packets through the logical network. - ovn-debug, a tool to simplify debugging of OVN setup. - Scripts and specs for building RPMs. What other documentation is available? -------------------------------------- .. TODO(stephenfin): Update with a link to the hosting site of the docs, once we know where that is To install OVN on a regular Linux or FreeBSD host, please read the `installation guide `__. For specifics around installation on a specific platform, refer to one of the `other installation guides `__ For answers to common questions, refer to the `FAQ `__. To learn about some advanced features of the Open vSwitch software switch, read the tutorial_. .. _tutorial: https://github.com/openvswitch/ovs/blob/main/Documentation/tutorials/ovs-advanced.rst Each OVN program is accompanied by a manpage. Many of the manpages are customized to your configuration as part of the build process, so we recommend building OVN before reading the manpages. License ------- The following is a summary of the licensing of files in this distribution. As mentioned, OVN is licensed under the open source Apache 2 license. Some files may be marked specifically with a different license, in which case that license applies to the file in question. File build-aux/cccl is licensed under the GNU General Public License, version 2. Contact ------- bugs@openvswitch.org ovn-25.09.0~git20250813.23884f5/TODO.rst000066400000000000000000000127651504532661100164570ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ============== OVN To-do List ============== * Refactor ovn-northd code to have separate functions to add logical flows for gateway logical routers and logical routers with distributed gateway port. * VLAN trunk ports. Russell Bryant: "Today that would require creating 4096 ports for the VM and attach to 4096 OVN networks, so doable, but not quite ideal." * Service function chaining. * Hitless upgrade, especially for data plane. * Dynamic IP to MAC binding enhancements. OVN has basic support for establishing IP to MAC bindings dynamically, using ARP. * Table size limiting. The table of MAC bindings must not be allowed to grow unreasonably large. * MTU handling (fragmentation on output) * Support multiple tunnel encapsulations in Chassis. So far, both ovn-controller and ovn-controller-vtep only allow chassis to have one tunnel encapsulation entry. We should extend the implementation to support multiple tunnel encapsulations. * Update learned MAC addresses from VTEP to OVN The VTEP gateway stores all MAC addresses learned from its physical interfaces in the 'Ucast_Macs_Local' and the 'Mcast_Macs_Local' tables. ovn-controller-vtep should be able to update that information back to ovn-sb database, so that other chassis know where to send packets destined to the extended external network instead of broadcasting. * Translate ovn-sb Multicast_Group table into VTEP config The ovn-controller-vtep daemon should be able to translate the Multicast_Group table entry in ovn-sb database into Mcast_Macs_Remote table configuration in VTEP database. * OVN OCF pacemaker script to support Active / Passive HA for OVN dbs provides the option to configure the inactivity_probe value. The default 5 seconds inactivity_probe value is not sufficient and ovsdb-server drops the client IDL connections for openstack deployments when the neutron server is heavily loaded. We need to find a proper solution to solve this issue instead of increasing the inactivity_probe value. * ACL * Support FTP ALGs. * OVN Interconnection * Packaging for Debian. * IP Multicast Relay * When connecting bridged logical switches (localnet) to logical routers with IP Multicast Relay enabled packets might get duplicated. We need to find a way of determining if routing has already been executed (on a different hypervisor) for the IP multicast packet being processed locally in the router pipeline. * ovn-controller Incremental processing * Implement I-P for datapath groups. * Implement I-P for route exchange relevant ports. * ovn-northd parallel logical flow processing * Multi-threaded logical flow computation was optimized for the case when datapath groups are disabled. Datpath groups are always enabled now so northd parallel processing should be revisited. * ovn-controller daemon module * Dumitru Ceara: Add a new module e.g. ovn/lib/daemon-ovn.c that wraps OVS' daemonize_start() call and initializes the additional things, like the unixctl commands. Or, we should move the APIs such as daemon_started_recently() to OVS's lib/daemon. * Chassis_Template_Var * Support template variables when tracing packets with ovn-trace. * Load Balancer templates * Support combining the VIP IP and port into a single template variable. * ovn-controller conditional monitoring * Improve sub-ports (with parent_port set) conditional monitoring; these are currently unconditionally monitored, even if ovn-monitor-all is set to false. * ovn-northd parallel build * Move the lflow build parallel processing from northd.c to lflow-mgr.c This would also ensure that the variables declared in northd.c (eg. thread_lflow_counter) are not externed in lflow-mgr.c. * Remove flows with `check_pkt_larger` when userspace datapath can handle PMTUD. (https://issues.redhat.com/browse/FDP-256) * Remove ssl_ciphersuites workaround for clustered databases from ovn-ctl after 26.03 release, assuming it will be an LTS release. * Dynamic Routing * Add incremental processing of en_dynamic_routes for stateful configuration changes. * The ovn-controller currently loads all Advertised_Route entries on startup. This is to prevent deleting our routes on restart. If we defer updating routes until we are sure to have loaded all necessary Advertised_Routes this could be changed. * Improve handling of the Learned_Route table in ovn-controller conditional monitoring; once a new local datapath is added we need to wait for monitoring conditions to update before we actually try to learn routes. Otherwise we could try to add duplicated Learned_Routes and the ovnsb commit would fail. ovn-25.09.0~git20250813.23884f5/TODO_SPLIT.rst000066400000000000000000000023701504532661100174210ustar00rootroot00000000000000.. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Convention for heading levels in OVN documentation: ======= Heading 0 (reserved for the title in a document) ------- Heading 1 ~~~~~~~ Heading 2 +++++++ Heading 3 ''''''' Heading 4 Avoid deeper levels because they do not render well. ======================== OVN/OVS Split To-do List ======================== * There are likely many unused files throughout the source tree since they pertain to OVS rather than OVN. These can also be removed from the repo. * Someone with a decent ability to write should give the README.rst file some polish (or even just rewrite it. I won't be offended). * Cleanup the acinclude.m4 and m4 folder ovn-25.09.0~git20250813.23884f5/Vagrantfile000066400000000000000000000160611504532661100173360ustar00rootroot00000000000000# -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.require_version ">=1.7.0" $bootstrap_ovs_fedora = <