diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index fc75581486..6f5139304a 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -238,6 +238,14 @@ jobs: if: matrix.m32 != '' run: sudo apt install -y gcc-multilib + - name: Reduce ASLR entropy + if: matrix.sanitizers != '' + # Asan in llvm 14 provided in ubuntu-22.04 is incompatible with + # high-entropy ASLR configured in much newer kernels that GitHub + # runners are using leading to random crashes: + # https://github.com/actions/runner-images/issues/9491 + run: sudo sysctl -w vm.mmap_rnd_bits=28 + - name: prepare run: ./.ci/linux-prepare.sh diff --git a/AUTHORS.rst b/AUTHORS.rst index aa9284fb16..80678854bd 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -588,6 +588,7 @@ David Evans davidjoshuaevans@gmail.com David Palma palma@onesource.pt David van Moolenbroek dvmoolenbroek@aimvalley.nl Derek Cormier derek.cormier@lab.ntt.co.jp +Derrick Lim derrick.lim@rakuten.com Dhaval Badiani dbadiani@vmware.com DK Moon Ding Zhi zhi.ding@6wind.com diff --git a/Documentation/intro/install/windows.rst b/Documentation/intro/install/windows.rst index fce099d5dc..efdb8aebce 100644 --- a/Documentation/intro/install/windows.rst +++ b/Documentation/intro/install/windows.rst @@ -112,7 +112,7 @@ The following explains the steps in some detail. `OpenSSL for Windows `__ Note down the directory where OpenSSL is installed (e.g.: - ``C:/OpenSSL-Win32``) for later use. + ``C:/OpenSSL-Win64``) for later use. .. note:: @@ -182,7 +182,7 @@ To configure with SSL support, add the requisite additional options: --localstatedir="C:/openvswitch/var" --sysconfdir="C:/openvswitch/etc" \ --with-pthread="C:/pthread" \ - --enable-ssl --with-openssl="C:/OpenSSL-Win32" + --enable-ssl --with-openssl="C:/OpenSSL-Win64" Finally, to the kernel module also: @@ -194,7 +194,7 @@ Finally, to the kernel module also: --localstatedir="C:/openvswitch/var" \ --sysconfdir="C:/openvswitch/etc" \ --with-pthread="C:/pthread" \ - --enable-ssl --with-openssl="C:/OpenSSL-Win32" \ + --enable-ssl --with-openssl="C:/OpenSSL-Win64" \ --with-vstudiotarget="" \ --with-vstudiotargetver="" diff --git a/NEWS b/NEWS index 8888fb3ec5..4bfb341cf4 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +v3.3.1 - xx xxx xxxx +-------------------- + v3.3.0 - 16 Feb 2024 -------------------- - OVSDB: diff --git a/configure.ac b/configure.ac index 05afbb9cc8..a3ea65c0fa 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ # limitations under the License. AC_PREREQ(2.63) -AC_INIT(openvswitch, 3.3.0, bugs@openvswitch.org) +AC_INIT(openvswitch, 3.3.1, bugs@openvswitch.org) AC_CONFIG_SRCDIR([vswitchd/ovs-vswitchd.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/debian/changelog b/debian/changelog index 2049ddaa26..22c767a4ce 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +openvswitch (3.3.1-1) unstable; urgency=low + [ Open vSwitch team ] + * New upstream version + + -- Open vSwitch team Fri, 16 Feb 2024 12:25:58 +0100 + openvswitch (3.3.0-1) unstable; urgency=low * New upstream version diff --git a/lib/bfd.c b/lib/bfd.c index 9af258917b..b8149e7897 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -1130,10 +1130,11 @@ bfd_set_state(struct bfd *bfd, enum state state, enum diag diag) if (!VLOG_DROP_INFO(&rl)) { struct ds ds = DS_EMPTY_INITIALIZER; - ds_put_format(&ds, "%s: BFD state change: %s->%s" - " \"%s\"->\"%s\".\n", + ds_put_format(&ds, "%s: BFD state change: (bfd.SessionState: %s," + " bfd.LocalDiag: \"%s\") -> (bfd.SessionState: %s," + " bfd.LocalDiag: \"%s\")\n", bfd->name, bfd_state_str(bfd->state), - bfd_state_str(state), bfd_diag_str(bfd->diag), + bfd_diag_str(bfd->diag), bfd_state_str(state), bfd_diag_str(diag)); bfd_put_details(&ds, bfd); VLOG_INFO("%s", ds_cstr(&ds)); diff --git a/lib/conntrack.c b/lib/conntrack.c index 013709bd62..6d02eaba8b 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -2637,25 +2637,19 @@ conntrack_dump_start(struct conntrack *ct, struct conntrack_dump *dump, dump->ct = ct; *ptot_bkts = 1; /* Need to clean up the callers. */ + dump->cursor = cmap_cursor_start(&ct->conns); return 0; } int conntrack_dump_next(struct conntrack_dump *dump, struct ct_dpif_entry *entry) { - struct conntrack *ct = dump->ct; long long now = time_msec(); - for (;;) { - struct cmap_node *cm_node = cmap_next_position(&ct->conns, - &dump->cm_pos); - if (!cm_node) { - break; - } - struct conn_key_node *keyn; - struct conn *conn; + struct conn_key_node *keyn; + struct conn *conn; - INIT_CONTAINER(keyn, cm_node, cm_node); + CMAP_CURSOR_FOR_EACH_CONTINUE (keyn, cm_node, &dump->cursor) { if (keyn->dir != CT_DIR_FWD) { continue; } diff --git a/lib/conntrack.h b/lib/conntrack.h index 0a888be455..6339701627 100644 --- a/lib/conntrack.h +++ b/lib/conntrack.h @@ -101,8 +101,8 @@ struct conntrack_dump { struct conntrack *ct; unsigned bucket; union { - struct cmap_position cm_pos; struct hmap_position hmap_pos; + struct cmap_cursor cursor; }; bool filter_zone; uint16_t zone; diff --git a/lib/dp-packet.c b/lib/dp-packet.c index 305822293b..df7bf8e6b3 100644 --- a/lib/dp-packet.c +++ b/lib/dp-packet.c @@ -592,6 +592,18 @@ dp_packet_ol_send_prepare(struct dp_packet *p, uint64_t flags) if (dp_packet_hwol_is_tunnel_geneve(p) || dp_packet_hwol_is_tunnel_vxlan(p)) { tnl_inner = true; + + /* If the TX interface doesn't support UDP tunnel offload but does + * support inner checksum offload and an outer UDP checksum is + * required, then we can't offload inner checksum either. As that would + * invalidate the outer checksum. */ + if (!(flags & NETDEV_TX_OFFLOAD_OUTER_UDP_CKSUM) && + dp_packet_hwol_is_outer_udp_cksum(p)) { + flags &= ~(NETDEV_TX_OFFLOAD_TCP_CKSUM | + NETDEV_TX_OFFLOAD_UDP_CKSUM | + NETDEV_TX_OFFLOAD_SCTP_CKSUM | + NETDEV_TX_OFFLOAD_IPV4_CKSUM); + } } if (dp_packet_hwol_tx_ip_csum(p)) { diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index 45f61930d4..8c52accff9 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -607,6 +607,9 @@ int netdev_dpdk_get_vid(const struct netdev_dpdk *dev); struct ingress_policer * netdev_dpdk_get_ingress_policer(const struct netdev_dpdk *dev); +static void netdev_dpdk_mbuf_dump(const char *prefix, const char *message, + const struct rte_mbuf *); + static bool is_dpdk_class(const struct netdev_class *class) { @@ -2569,9 +2572,29 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf) struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf); struct tcp_header *th; - if (!(mbuf->ol_flags & (RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_L4_MASK - | RTE_MBUF_F_TX_TCP_SEG))) { - mbuf->ol_flags &= ~(RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IPV6); + const uint64_t all_requests = (RTE_MBUF_F_TX_IP_CKSUM | + RTE_MBUF_F_TX_L4_MASK | + RTE_MBUF_F_TX_OUTER_IP_CKSUM | + RTE_MBUF_F_TX_OUTER_UDP_CKSUM | + RTE_MBUF_F_TX_TCP_SEG); + const uint64_t all_marks = (RTE_MBUF_F_TX_IPV4 | + RTE_MBUF_F_TX_IPV6 | + RTE_MBUF_F_TX_OUTER_IPV4 | + RTE_MBUF_F_TX_OUTER_IPV6 | + RTE_MBUF_F_TX_TUNNEL_MASK); + + if (!(mbuf->ol_flags & all_requests)) { + /* No offloads requested, no marks should be set. */ + mbuf->ol_flags &= ~all_marks; + + uint64_t unexpected = mbuf->ol_flags & RTE_MBUF_F_TX_OFFLOAD_MASK; + if (OVS_UNLIKELY(unexpected)) { + VLOG_WARN_RL(&rl, "%s: Unexpected Tx offload flags: %#"PRIx64, + netdev_get_name(&dev->up), unexpected); + netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up), + "Packet with unexpected ol_flags", mbuf); + return false; + } return true; } @@ -2664,6 +2687,35 @@ netdev_dpdk_prep_hwol_batch(struct netdev_dpdk *dev, struct rte_mbuf **pkts, return cnt; } +static void +netdev_dpdk_mbuf_dump(const char *prefix, const char *message, + const struct rte_mbuf *mbuf) +{ + static struct vlog_rate_limit dump_rl = VLOG_RATE_LIMIT_INIT(5, 5); + char *response = NULL; + FILE *stream; + size_t size; + + if (VLOG_DROP_DBG(&dump_rl)) { + return; + } + + stream = open_memstream(&response, &size); + if (!stream) { + VLOG_ERR("Unable to open memstream for mbuf dump: %s.", + ovs_strerror(errno)); + return; + } + + rte_pktmbuf_dump(stream, mbuf, rte_pktmbuf_pkt_len(mbuf)); + + fclose(stream); + + VLOG_DBG(prefix ? "%s: %s:\n%s" : "%s%s:\n%s", + prefix ? prefix : "", message, response); + free(response); +} + /* Tries to transmit 'pkts' to txq 'qid' of device 'dev'. Takes ownership of * 'pkts', even in case of failure. * @@ -2680,6 +2732,8 @@ netdev_dpdk_eth_tx_burst(struct netdev_dpdk *dev, int qid, VLOG_WARN_RL(&rl, "%s: Output batch contains invalid packets. " "Only %u/%u are valid: %s", netdev_get_name(&dev->up), nb_tx_prep, cnt, rte_strerror(rte_errno)); + netdev_dpdk_mbuf_dump(netdev_get_name(&dev->up), + "First invalid packet", pkts[nb_tx_prep]); } while (nb_tx != nb_tx_prep) { diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index cd7e85a818..e8bbf8d514 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -39,6 +39,7 @@ #include "pcap-file.h" #include "openvswitch/poll-loop.h" #include "openvswitch/shash.h" +#include "ovs-router.h" #include "sset.h" #include "stream.h" #include "unaligned.h" @@ -2084,11 +2085,20 @@ netdev_dummy_ip4addr(struct unixctl_conn *conn, int argc OVS_UNUSED, if (netdev && is_dummy_class(netdev->netdev_class)) { struct in_addr ip, mask; + struct in6_addr ip6; + uint32_t plen; char *error; - error = ip_parse_masked(argv[2], &ip.s_addr, &mask.s_addr); + error = ip_parse_cidr(argv[2], &ip.s_addr, &plen); if (!error) { + mask.s_addr = be32_prefix_mask(plen); netdev_dummy_add_in4(netdev, ip, mask); + + /* Insert local route entry for the new address. */ + in6_addr_set_mapped_ipv4(&ip6, ip.s_addr); + ovs_router_force_insert(0, &ip6, plen + 96, true, argv[1], + &in6addr_any, &ip6); + unixctl_command_reply(conn, "OK"); } else { unixctl_command_reply_error(conn, error); @@ -2118,6 +2128,11 @@ netdev_dummy_ip6addr(struct unixctl_conn *conn, int argc OVS_UNUSED, mask = ipv6_create_mask(plen); netdev_dummy_add_in6(netdev, &ip6, &mask); + + /* Insert local route entry for the new address. */ + ovs_router_force_insert(0, &ip6, plen, true, argv[1], + &in6addr_any, &ip6); + unixctl_command_reply(conn, "OK"); } else { unixctl_command_reply_error(conn, error); diff --git a/lib/ovs-router.c b/lib/ovs-router.c index ca014d80ed..3d84c9a30a 100644 --- a/lib/ovs-router.c +++ b/lib/ovs-router.c @@ -330,6 +330,20 @@ ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen, } } +/* The same as 'ovs_router_insert', but it adds the route even if updates + * from the system routing table are disabled. Used for unit tests. */ +void +ovs_router_force_insert(uint32_t mark, const struct in6_addr *ip_dst, + uint8_t plen, bool local, const char output_bridge[], + const struct in6_addr *gw, + const struct in6_addr *prefsrc) +{ + uint8_t priority = local ? plen + 64 : plen; + + ovs_router_insert__(mark, priority, local, ip_dst, plen, + output_bridge, gw, prefsrc); +} + static void rt_entry_delete__(const struct cls_rule *cr) { diff --git a/lib/ovs-router.h b/lib/ovs-router.h index eb4ff85d9e..d7dc7e55f3 100644 --- a/lib/ovs-router.h +++ b/lib/ovs-router.h @@ -34,6 +34,11 @@ void ovs_router_insert(uint32_t mark, const struct in6_addr *ip_dst, uint8_t plen, bool local, const char output_bridge[], const struct in6_addr *gw, const struct in6_addr *prefsrc); +void ovs_router_force_insert(uint32_t mark, const struct in6_addr *ip_dst, + uint8_t plen, bool local, + const char output_bridge[], + const struct in6_addr *gw, + const struct in6_addr *prefsrc); void ovs_router_flush(void); void ovs_router_disable_system_routing_table(void); diff --git a/m4/ax_check_openssl.m4 b/m4/ax_check_openssl.m4 index 281d4dc65e..faa5babde2 100644 --- a/m4/ax_check_openssl.m4 +++ b/m4/ax_check_openssl.m4 @@ -81,7 +81,8 @@ AC_DEFUN([AX_CHECK_OPENSSL], [ SSL_INCLUDES="-I$ssldir/include" SSL_LDFLAGS="-L$ssldir/lib" if test "$WIN32" = "yes"; then - SSL_LIBS="-lssleay32 -llibeay32" + SSL_LDFLAGS="$SSL_LDFLAGS -L$ssldir/lib/VC/x64/MT" + SSL_LIBS="-llibssl -llibcrypto" SSL_DIR=/$(echo ${ssldir} | ${SED} -e 's/://') else SSL_LIBS="-lssl -lcrypto" diff --git a/ofproto/bond.c b/ofproto/bond.c index cfdf44f854..c31869a4c7 100644 --- a/ofproto/bond.c +++ b/ofproto/bond.c @@ -186,7 +186,7 @@ static struct bond_member *choose_output_member(const struct bond *, struct flow_wildcards *, uint16_t vlan) OVS_REQ_RDLOCK(rwlock); -static void update_recirc_rules__(struct bond *); +static void update_recirc_rules(struct bond *) OVS_REQ_WRLOCK(rwlock); static bool bond_may_recirc(const struct bond *); static void bond_update_post_recirc_rules__(struct bond *, bool force) OVS_REQ_WRLOCK(rwlock); @@ -299,7 +299,10 @@ bond_unref(struct bond *bond) } free(bond->hash); bond->hash = NULL; - update_recirc_rules__(bond); + + ovs_rwlock_wrlock(&rwlock); + update_recirc_rules(bond); + ovs_rwlock_unlock(&rwlock); hmap_destroy(&bond->pr_rule_ops); free(bond->primary); @@ -331,17 +334,8 @@ add_pr_rule(struct bond *bond, const struct match *match, hmap_insert(&bond->pr_rule_ops, &pr_op->hmap_node, hash); } -/* This function should almost never be called directly. - * 'update_recirc_rules()' should be called instead. Since - * this function modifies 'bond->pr_rule_ops', it is only - * safe when 'rwlock' is held. - * - * However, when the 'bond' is the only reference in the system, - * calling this function avoid acquiring lock only to satisfy - * lock annotation. Currently, only 'bond_unref()' calls - * this function directly. */ static void -update_recirc_rules__(struct bond *bond) +update_recirc_rules(struct bond *bond) OVS_REQ_WRLOCK(rwlock) { struct match match; struct bond_pr_rule_op *pr_op; @@ -407,6 +401,15 @@ update_recirc_rules__(struct bond *bond) VLOG_ERR("failed to remove post recirculation flow %s", err_s); free(err_s); + } else if (bond->hash) { + /* If the flow deletion failed, a subsequent call to + * ofproto_dpif_add_internal_flow() would just modify the + * flow preserving its statistics. Therefore, only reset + * the entry's byte counter if it succeeds. */ + uint32_t hash = pr_op->match.flow.dp_hash & BOND_MASK; + struct bond_entry *entry = &bond->hash[hash]; + + entry->pr_tx_bytes = 0; } hmap_remove(&bond->pr_rule_ops, &pr_op->hmap_node); @@ -421,12 +424,6 @@ update_recirc_rules__(struct bond *bond) ofpbuf_uninit(&ofpacts); } -static void -update_recirc_rules(struct bond *bond) - OVS_REQ_RDLOCK(rwlock) -{ - update_recirc_rules__(bond); -} /* Updates 'bond''s overall configuration to 's'. * diff --git a/ofproto/ofproto-dpif-trace.c b/ofproto/ofproto-dpif-trace.c index b86e7fe07e..87506aa785 100644 --- a/ofproto/ofproto-dpif-trace.c +++ b/ofproto/ofproto-dpif-trace.c @@ -845,17 +845,35 @@ ofproto_trace(struct ofproto_dpif *ofproto, const struct flow *flow, bool names) { struct ovs_list recirc_queue = OVS_LIST_INITIALIZER(&recirc_queue); + int recirculations = 0; + ofproto_trace__(ofproto, flow, packet, &recirc_queue, ofpacts, ofpacts_len, output, names); struct oftrace_recirc_node *recirc_node; LIST_FOR_EACH_POP (recirc_node, node, &recirc_queue) { + if (recirculations++ > 4096) { + ds_put_cstr(output, "\n\n"); + ds_put_char_multiple(output, '=', 79); + ds_put_cstr(output, "\nTrace reached the recirculation limit." + " Sopping the trace here."); + ds_put_format(output, + "\nQueued but not processed: %"PRIuSIZE + " recirculations.", + ovs_list_size(&recirc_queue) + 1); + oftrace_recirc_node_destroy(recirc_node); + break; + } ofproto_trace_recirc_node(recirc_node, next_ct_states, output); ofproto_trace__(ofproto, &recirc_node->flow, recirc_node->packet, &recirc_queue, ofpacts, ofpacts_len, output, names); oftrace_recirc_node_destroy(recirc_node); } + /* Destroy remaining recirculation nodes, if any. */ + LIST_FOR_EACH_POP (recirc_node, node, &recirc_queue) { + oftrace_recirc_node_destroy(recirc_node); + } } void diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 1cf4d5f7c9..89f183182e 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -3815,6 +3815,8 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport, if (flow->tunnel.ip_src) { in6_addr_set_mapped_ipv4(&s_ip6, flow->tunnel.ip_src); + } else if (ipv6_addr_is_set(&flow->tunnel.ipv6_src)) { + s_ip6 = flow->tunnel.ipv6_src; } err = tnl_route_lookup_flow(ctx, flow, &d_ip6, &s_ip6, &out_dev); diff --git a/tests/nsh.at b/tests/nsh.at index 55296e5593..0040a50b36 100644 --- a/tests/nsh.at +++ b/tests/nsh.at @@ -521,51 +521,45 @@ AT_CHECK([ set interface vxlangpe32 type=vxlan options:exts=gpe options:remote_ip=30.0.0.2 options:packet_type=ptap ofport_request=3020 ovs-appctl netdev-dummy/ip4addr br-p1 10.0.0.1/24 - ovs-appctl ovs/route/add 10.0.0.0/24 br-p1 ovs-appctl tnl/arp/set br-p1 10.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p1 10.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p1 10.0.0.3 $HWADDR_BRP3 ovs-appctl netdev-dummy/ip4addr br-p2 20.0.0.2/24 - ovs-appctl ovs/route/add 20.0.0.0/24 br-p2 ovs-appctl tnl/arp/set br-p2 20.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p2 20.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p2 20.0.0.3 $HWADDR_BRP3 ovs-appctl netdev-dummy/ip4addr br-p3 30.0.0.3/24 - ovs-appctl ovs/route/add 30.0.0.0/24 br-p3 ovs-appctl tnl/arp/set br-p3 30.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p3 30.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p3 30.0.0.3 $HWADDR_BRP3 ], [0], [stdout]) AT_CHECK([ - ovs-appctl ovs/route/add 10.0.0.0/24 br-p1 ovs-appctl tnl/arp/set br-p1 10.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p1 10.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p1 10.0.0.3 $HWADDR_BRP3 ], [0], [stdout]) AT_CHECK([ - ovs-appctl ovs/route/add 20.0.0.0/24 br-p2 ovs-appctl tnl/arp/set br-p2 20.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p2 20.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p2 20.0.0.3 $HWADDR_BRP3 ], [0], [stdout]) AT_CHECK([ - ovs-appctl ovs/route/add 30.0.0.0/24 br-p3 ovs-appctl tnl/arp/set br-p3 30.0.0.1 $HWADDR_BRP1 ovs-appctl tnl/arp/set br-p3 30.0.0.2 $HWADDR_BRP2 ovs-appctl tnl/arp/set br-p3 30.0.0.3 $HWADDR_BRP3 ], [0], [stdout]) AT_CHECK([ - ovs-appctl ovs/route/show | grep User: + ovs-appctl ovs/route/show | grep Cached: | sort ], [0], [dnl -User: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 -User: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 -User: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 +Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 local +Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 local +Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 local ]) AT_CHECK([ diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index e305e7b9cd..a1393f7f8e 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -547,6 +547,23 @@ ovs-appctl time/warp 1000 100 ovs-appctl bond/show > bond3.txt AT_CHECK([sed -n '/member p2/,/^$/p' bond3.txt | grep 'hash'], [0], [ignore]) +# Check that both ports doing down and back up doesn't break statistics. +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p1 down], 0, [OK +]) +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 down], 0, [OK +]) +ovs-appctl time/warp 1000 100 +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p1 up], 0, [OK +]) +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state p2 up], 0, [OK +]) +ovs-appctl time/warp 1000 100 + +AT_CHECK([SEND_TCP_BOND_PKTS([p5], [5], [65500])]) +# We sent 49125 KB of data total in 3 batches. No hash should have more +# than that amount of load. Just checking that it is within 5 digits. +AT_CHECK([ovs-appctl bond/show | grep -E '[[0-9]]{6}'], [1]) + OVS_VSWITCHD_STOP() AT_CLEANUP @@ -7653,12 +7670,14 @@ dummy@ovs-dummy: hit:0 missed:0 vm1 5/3: (dummy: ifindex=2011) ]) -dnl set up route to 1.1.2.92 via br0 and action=normal +dnl Add 1.1.2.92 to br0 and action=normal AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK -]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +]) dnl Prime ARP Cache for 1.1.2.92 AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)']) @@ -7669,10 +7688,13 @@ ovs-vsctl \ --id=@sf create sflow targets=\"127.0.0.1:$SFLOW_PORT\" agent=127.0.0.1 \ header=128 sampling=1 polling=0 -dnl set up route to 192.168.1.2 via br0 +dnl Add 192.168.1.2 to br0, AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 192.168.1.1/16], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 192.168.0.0/16 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 192.168.0.0/16 dev br0 SRC 192.168.1.1 local ]) dnl add rule for int-br to force packet onto tunnel. There is no ifindex diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at index b8ccc4c8e2..ce6d32aee1 100644 --- a/tests/ovsdb-server.at +++ b/tests/ovsdb-server.at @@ -936,8 +936,10 @@ AT_CHECK_UNQUOTED( [ignore]) # The error message for being unable to negotiate a shared ciphersuite # is 'sslv3 alert handshake failure'. This is not the clearest message. +# In openssl 3.2.0 all the error messages were updated to replace 'sslv3' +# with 'ssl/tls'. AT_CHECK_UNQUOTED( - [grep "sslv3 alert handshake failure" output], [0], + [grep -E "(sslv3|ssl/tls) alert handshake failure" output], [0], [stdout], [ignore]) OVSDB_SERVER_SHUTDOWN([" diff --git a/tests/packet-type-aware.at b/tests/packet-type-aware.at index 14cebf6efa..d634930fd5 100644 --- a/tests/packet-type-aware.at +++ b/tests/packet-type-aware.at @@ -142,30 +142,27 @@ AT_CHECK([ ### Setup GRE tunnels AT_CHECK([ ovs-appctl netdev-dummy/ip4addr br-p1 10.0.0.1/24 && - ovs-appctl ovs/route/add 10.0.0.0/24 br-p1 && ovs-appctl tnl/arp/set br-p1 10.0.0.1 $HWADDR_BRP1 && ovs-appctl tnl/arp/set br-p1 10.0.0.2 $HWADDR_BRP2 && ovs-appctl tnl/arp/set br-p1 10.0.0.3 $HWADDR_BRP3 && ovs-appctl netdev-dummy/ip4addr br-p2 20.0.0.2/24 && - ovs-appctl ovs/route/add 20.0.0.0/24 br-p2 && ovs-appctl tnl/arp/set br-p2 20.0.0.1 $HWADDR_BRP1 && ovs-appctl tnl/arp/set br-p2 20.0.0.2 $HWADDR_BRP2 && ovs-appctl tnl/arp/set br-p2 20.0.0.3 $HWADDR_BRP3 && ovs-appctl netdev-dummy/ip4addr br-p3 30.0.0.3/24 && - ovs-appctl ovs/route/add 30.0.0.0/24 br-p3 && ovs-appctl tnl/arp/set br-p3 30.0.0.1 $HWADDR_BRP1 && ovs-appctl tnl/arp/set br-p3 30.0.0.2 $HWADDR_BRP2 && ovs-appctl tnl/arp/set br-p3 30.0.0.3 $HWADDR_BRP3 ], [0], [ignore]) AT_CHECK([ - ovs-appctl ovs/route/show | grep User: + ovs-appctl ovs/route/show | grep Cached: | sort ], [0], [dnl -User: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 -User: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 -User: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 +Cached: 10.0.0.0/24 dev br-p1 SRC 10.0.0.1 local +Cached: 20.0.0.0/24 dev br-p2 SRC 20.0.0.2 local +Cached: 30.0.0.0/24 dev br-p3 SRC 30.0.0.3 local ]) AT_CHECK([ @@ -681,14 +678,13 @@ AT_CHECK([ AT_CHECK([ ovs-appctl netdev-dummy/ip4addr br2 10.0.0.1/24 && - ovs-appctl ovs/route/add 10.0.0.0/24 br2 && ovs-appctl tnl/arp/set br2 10.0.0.2 de:af:be:ef:ba:be ], [0], [ignore]) AT_CHECK([ - ovs-appctl ovs/route/show | grep User: + ovs-appctl ovs/route/show | grep Cached: ], [0], [dnl -User: 10.0.0.0/24 dev br2 SRC 10.0.0.1 +Cached: 10.0.0.0/24 dev br2 SRC 10.0.0.1 local ]) @@ -955,7 +951,6 @@ AT_CHECK([ AT_CHECK([ ovs-appctl netdev-dummy/ip4addr br0 20.0.0.1/24 && - ovs-appctl ovs/route/add 20.0.0.2/24 br0 && ovs-appctl tnl/neigh/set br0 20.0.0.1 aa:bb:cc:00:00:01 && ovs-appctl tnl/neigh/set br0 20.0.0.2 aa:bb:cc:00:00:02 ], [0], [ignore]) @@ -963,9 +958,9 @@ AT_CHECK([ ovs-appctl time/warp 1000 AT_CHECK([ - ovs-appctl ovs/route/show | grep User + ovs-appctl ovs/route/show | grep Cached: ],[0], [dnl -User: 20.0.0.0/24 dev br0 SRC 20.0.0.1 +Cached: 20.0.0.0/24 dev br0 SRC 20.0.0.1 local ]) AT_CHECK([ diff --git a/tests/system-layer3-tunnels.at b/tests/system-layer3-tunnels.at index 6fbdedb64f..5dcdd2afae 100644 --- a/tests/system-layer3-tunnels.at +++ b/tests/system-layer3-tunnels.at @@ -98,61 +98,6 @@ NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -W 2 10.1.1.2 | FORMAT_PING OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP -AT_SETUP([layer3 - use non-local port as tunnel endpoint]) - -OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1]) -AT_CHECK([ovs-vsctl add-port br0 vtep0 -- set int vtep0 type=dummy], [0]) -AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy], [0]) -AT_CHECK([ovs-vsctl add-port int-br t1 -- set Interface t1 type=gre \ - options:remote_ip=1.1.2.92 ofport_request=3], [0]) - -AT_CHECK([ovs-appctl dpif/show], [0], [dnl -dummy@ovs-dummy: hit:0 missed:0 - br0: - br0 65534/100: (dummy-internal) - p0 1/1: (dummy) - vtep0 2/2: (dummy) - int-br: - int-br 65534/3: (dummy-internal) - t1 3/4: (gre: remote_ip=1.1.2.92) -]) - -AT_CHECK([ovs-appctl netdev-dummy/ip4addr vtep0 1.1.2.88/24], [0], [OK -]) -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 vtep0], [0], [OK -]) -AT_CHECK([ovs-ofctl add-flow br0 action=normal]) -AT_CHECK([ovs-ofctl add-flow int-br action=normal]) - -dnl Use arp request and reply to achieve tunnel next hop mac binding -dnl By default, vtep0's MAC address is aa:55:aa:55:00:03 -AT_CHECK([ovs-appctl netdev-dummy/receive vtep0 'recirc_id(0),in_port(2),eth(dst=ff:ff:ff:ff:ff:ff,src=aa:55:aa:55:00:03),eth_type(0x0806),arp(tip=1.1.2.92,sip=1.1.2.88,op=1,sha=aa:55:aa:55:00:03,tha=00:00:00:00:00:00)']) -AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:03),eth_type(0x0806),arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=aa:55:aa:55:00:03)']) - -AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl -1.1.2.92 f8:bc:12:44:34:b6 br0 -]) - -AT_CHECK([ovs-appctl ovs/route/show | tail -n+2 | sort], [0], [dnl -User: 1.1.2.0/24 dev vtep0 SRC 1.1.2.88 -]) - -dnl Check GRE tunnel pop -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:03),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout]) - -AT_CHECK([tail -1 stdout], [0], - [Datapath actions: tnl_pop(4) -]) - -dnl Check GRE tunnel push -AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),eth(dst=f9:bc:12:44:34:b6,src=af:55:aa:55:00:03),eth_type(0x0800),ipv4(src=1.1.3.88,dst=1.1.3.92,proto=1,tos=0,ttl=64,frag=no)'], [0], [stdout]) -AT_CHECK([tail -1 stdout], [0], - [Datapath actions: tnl_push(tnl_port(4),header(size=38,type=3,eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),gre((flags=0x0,proto=0x6558))),out_port(2)),1 -]) - -OVS_VSWITCHD_STOP -AT_CLEANUP - AT_SETUP([layer3 - ping over MPLS Bareudp]) OVS_CHECK_BAREUDP() OVS_TRAFFIC_VSWITCHD_START([_ADD_BR([br1])]) diff --git a/tests/system-traffic.at b/tests/system-traffic.at index 98e494abf4..2d12d558ec 100644 --- a/tests/system-traffic.at +++ b/tests/system-traffic.at @@ -6388,6 +6388,7 @@ OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - SNAT with port range with exhaustion]) +OVS_CHECK_GITHUB_ACTION() CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() OVS_TRAFFIC_VSWITCHD_START() @@ -8389,6 +8390,53 @@ AT_CHECK([ovs-pcap client.pcap | grep 000000002010000000002000], [0], [dnl OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([conntrack - Flush many conntrack entries by port]) +CHECK_CONNTRACK() +OVS_TRAFFIC_VSWITCHD_START() + +ADD_NAMESPACES(at_ns0, at_ns1) + +ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") +ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") + +AT_DATA([flows.txt], [dnl +priority=100,in_port=1,udp,action=ct(zone=1,commit),2 +]) + +AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) + +dnl 20 packets from port 1 and 1 packet from port 2. +flow_l3="\ + eth_src=50:54:00:00:00:09,eth_dst=50:54:00:00:00:0a,dl_type=0x0800,\ + nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_proto=17,nw_ttl=64,nw_frag=no" + +for i in $(seq 1 20); do + frame=$(ovs-ofctl compose-packet --bare "$flow_l3, udp_src=1,udp_dst=$i") + AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=$frame actions=resubmit(,0)"]) +done +frame=$(ovs-ofctl compose-packet --bare "$flow_l3, udp_src=2,udp_dst=1") +AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=$frame actions=resubmit(,0)"]) + +: > conntrack + +for i in $(seq 1 20); do + echo "udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=${i}),reply=(src=10.1.1.2,dst=10.1.1.1,sport=${i},dport=1),zone=1" >> conntrack +done +echo "udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=2,dport=1),reply=(src=10.1.1.2,dst=10.1.1.1,sport=1,dport=2),zone=1" >> conntrack + +sort conntrack > expout + +AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=1 | grep -F "src=10.1.1.1," | sort ], [0], [expout]) + +dnl Check that flushing conntrack by port 1 flush all ct for port 1 but keeps ct for port 2. +AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=1 'ct_nw_proto=17,ct_tp_src=1']) +AT_CHECK([ovs-appctl dpctl/dump-conntrack zone=1 | grep -F "src=10.1.1.1," | sort ], [0], [dnl +udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=2,dport=1),reply=(src=10.1.1.2,dst=10.1.1.1,sport=1,dport=2),zone=1 +]) + +OVS_TRAFFIC_VSWITCHD_STOP +AT_CLEANUP + AT_BANNER([IGMP]) AT_SETUP([IGMP - flood under normal action]) diff --git a/tests/tunnel-push-pop-ipv6.at b/tests/tunnel-push-pop-ipv6.at index a8dd28c5b5..3f2cf84292 100644 --- a/tests/tunnel-push-pop-ipv6.at +++ b/tests/tunnel-push-pop-ipv6.at @@ -19,11 +19,12 @@ AT_CHECK([ovs-vsctl add-port int-br3 t3 -- set Interface t3 type=srv6 \ options:srv6_flowlabel=compute \ ], [0]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 2001:cafe::0/24 br0], [0], [OK +dnl Checking that a local routes for added IPs were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local ]) AT_CHECK([ovs-appctl tnl/neigh/set br0 2001:cafe::91 aa:55:aa:55:00:01], [0], [OK ]) @@ -105,13 +106,15 @@ dummy@ovs-dummy: hit:0 missed:0 t2 2/6: (ip6gre: remote_ip=2001:cafe::92) ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP addresses. AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 2001:cafe::92/24 br0], [0], [OK +dnl Checking that a local routes for added IPs were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -179,13 +182,15 @@ dummy@ovs-dummy: hit:0 missed:0 t3 3/6: (ip6erspan: erspan_dir=1, erspan_hwid=0x7, erspan_ver=2, key=567, remote_ip=2001:cafe::93) ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP addresses. AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 2001:cafe::92/24 br0], [0], [OK +dnl Checking that a local routes for added IPs were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -316,14 +321,15 @@ srv6_sys (6) ref_cnt=1 vxlan_sys_4789 (4789) ref_cnt=2 ]) - -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP addresses. AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 2001:cafe::92/24 br0], [0], [OK +dnl Checking that a local routes for added IPs were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -636,3 +642,87 @@ Listening ports: OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([tunnel_push_pop_ipv6 - local_ip configuration]) + +OVS_VSWITCHD_START( + [add-port br0 p0 \ + -- set Interface p0 type=dummy ofport_request=1 \ + other-config:hwaddr=aa:55:aa:55:00:00]) +AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg]) +AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy]) +AT_CHECK([ovs-vsctl add-port int-br t2 \ + -- set Interface t2 type=geneve \ + options:local_ip=2001:beef::88 \ + options:remote_ip=2001:cafe::92 \ + options:key=123 ofport_request=2]) + +dnl Setup multiple IP addresses. +AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/64], [0], [OK +]) +AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:beef::88/64], [0], [OK +]) +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 2001:beef::/64 dev br0 SRC 2001:beef::88 local +Cached: 2001:cafe::/64 dev br0 SRC 2001:cafe::88 local +]) +AT_CHECK([ovs-ofctl add-flow br0 action=normal]) +AT_CHECK([ovs-ofctl add-flow int-br action=normal]) + +dnl This Neighbor Advertisement from p0 has two effects: +dnl 1. The neighbor cache will learn that 2001:cafe::92 is at f8:bc:12:44:34:b6. +dnl 2. The br0 mac learning will learn that f8:bc:12:44:34:b6 is on p0. +AT_CHECK([ovs-appctl netdev-dummy/receive p0 dnl + 'recirc_id(0),in_port(1),dnl + eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:00),eth_type(0x86dd),dnl + ipv6(src=2001:cafe::92,dst=2001:cafe::88,label=0,proto=58,tclass=0,hlimit=255,frag=no),dnl + icmpv6(type=136,code=0),dnl + nd(target=2001:cafe::92,sll=00:00:00:00:00:00,tll=f8:bc:12:44:34:b6)' +]) + +dnl Check that local_ip is used for encapsulation in the trace. +AT_CHECK([ovs-appctl ofproto/trace int-br in_port=LOCAL \ + | grep -E 'tunnel|actions'], [0], [dnl + -> output to native tunnel + -> tunneling to 2001:cafe::92 via br0 + -> tunneling from aa:55:aa:55:00:00 2001:beef::88 to f8:bc:12:44:34:b6 2001:cafe::92 +Datapath actions: tnl_push(tnl_port(6081),header(size=70,type=5,dnl +eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),dnl +ipv6(src=2001:beef::88,dst=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),dnl +udp(src=0,dst=6081,csum=0xffff),geneve(vni=0x7b)),out_port(100)),1 +]) + +dnl Now check that the packet actually has the local_ip in the header. +AT_CHECK([ovs-vsctl -- set Interface p0 options:tx_pcap=p0.pcap]) + +packet=50540000000a5054000000091234 +eth=f8bc124434b6aa55aa55000086dd +ip6=60000000001e11402001beef0000000000000000000000882001cafe000000000000000000000092 +dnl Source port is based on a packet hash, so it may differ depending on the +dnl compiler flags and CPU type. Same for UDP checksum. Masked with '....'. +udp=....17c1001e.... +geneve=0000655800007b00 +encap=${eth}${ip6}${udp}${geneve} +dnl Output to tunnel from a int-br internal port. +dnl Checking that the packet arrived and it was correctly encapsulated. +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}"]) +OVS_WAIT_UNTIL([test $(ovs-pcap p0.pcap | grep -c "${encap}${packet}") -eq 1]) +dnl Sending again to exercise the non-miss upcall path. +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}"]) +OVS_WAIT_UNTIL([test $(ovs-pcap p0.pcap | grep -c "${encap}${packet}") -eq 2]) + +dnl Finally, checking that the datapath flow also has a local_ip. +AT_CHECK([ovs-appctl dpctl/dump-flows | grep tnl_push \ + | strip_ufid | strip_used], [0], [dnl +recirc_id(0),in_port(2),packet_type(ns=0,id=0),dnl +eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x1234), dnl +packets:1, bytes:14, used:0.0s, dnl +actions:tnl_push(tnl_port(6081),header(size=70,type=5,dnl +eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x86dd),dnl +ipv6(src=2001:beef::88,dst=2001:cafe::92,label=0,proto=17,tclass=0x0,hlimit=64),dnl +udp(src=0,dst=6081,csum=0xffff),geneve(vni=0x7b)),out_port(100)),1 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at index b1440f5904..97405636f9 100644 --- a/tests/tunnel-push-pop.at +++ b/tests/tunnel-push-pop.at @@ -30,17 +30,15 @@ dummy@ovs-dummy: hit:0 missed:0 t4 5/3: (erspan: erspan_dir=flow, erspan_hwid=flow, erspan_idx=flow, erspan_ver=flow, key=56, remote_ip=flow) ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP addresses. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) - -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK -]) - -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0 pkt_mark=1234], [0], [OK +dnl Checking that a local routes for added IPs were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -237,18 +235,21 @@ dummy@ovs-dummy: hit:0 missed:0 t8 9/2152: (gtpu: key=123, remote_ip=1.1.2.92) ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP addresses. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 2001:cafe::88/24], [0], [OK ]) - -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK -]) - +dnl Add a static route with a mark. AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0 pkt_mark=1234], [0], [OK ]) +dnl Checking that local routes for added IPs and the static route with a mark +dnl were successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep br0 | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2001:ca00::/24 dev br0 SRC 2001:cafe::88 local +User: 1.1.2.0/24 MARK 1234 dev br0 SRC 1.1.2.88 +]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -690,12 +691,12 @@ AT_CHECK([ovs-vsctl add-port int-br t2 -- set Interface t2 type=geneve \ options:remote_ip=1.1.2.92 options:key=123 ofport_request=2 \ ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) - -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -731,11 +732,12 @@ AT_CHECK([ovs-vsctl add-port int-br t2 dnl -- set Interface t2 type=geneve options:remote_ip=1.1.2.92 dnl options:key=123 ofport_request=2]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -777,6 +779,88 @@ AT_CHECK([ovs-appctl dpctl/dump-flows | grep -q 'slow_path(action)'], [0]) OVS_VSWITCHD_STOP AT_CLEANUP +AT_SETUP([tunnel_push_pop - local_ip configuration]) + +OVS_VSWITCHD_START( + [add-port br0 p0 \ + -- set Interface p0 type=dummy ofport_request=1 \ + other-config:hwaddr=aa:55:aa:55:00:00]) +AT_CHECK([ovs-appctl vlog/set dpif_netdev:dbg]) +AT_CHECK([ovs-vsctl add-br int-br -- set bridge int-br datapath_type=dummy]) +AT_CHECK([ovs-vsctl add-port int-br t2 \ + -- set Interface t2 type=geneve \ + options:local_ip=2.2.2.88 \ + options:remote_ip=1.1.2.92 \ + options:key=123 ofport_request=2]) + +dnl Setup multiple IP addresses. +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK +]) +AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 2.2.2.88/24], [0], [OK +]) +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached | sort], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local +Cached: 2.2.2.0/24 dev br0 SRC 2.2.2.88 local +]) +AT_CHECK([ovs-ofctl add-flow br0 action=normal]) +AT_CHECK([ovs-ofctl add-flow int-br action=normal]) + +dnl This ARP reply from p0 has two effects: +dnl 1. The ARP cache will learn that 1.1.2.92 is at f8:bc:12:44:34:b6. +dnl 2. The br0 mac learning will learn that f8:bc:12:44:34:b6 is on p0. +AT_CHECK([ovs-appctl netdev-dummy/receive p0 dnl + 'recirc_id(0),in_port(1),dnl + eth(src=f8:bc:12:44:34:b6,dst=ff:ff:ff:ff:ff:ff),eth_type(0x0806),dnl + arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=00:00:00:00:00:00)' +]) + +dnl Check that local_ip is used for encapsulation in the trace. +AT_CHECK([ovs-appctl ofproto/trace int-br in_port=LOCAL \ + | grep -E 'tunnel|actions'], [0], [dnl + -> output to native tunnel + -> tunneling to 1.1.2.92 via br0 + -> tunneling from aa:55:aa:55:00:00 2.2.2.88 to f8:bc:12:44:34:b6 1.1.2.92 +Datapath actions: tnl_push(tnl_port(6081),header(size=50,type=5,dnl +eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),dnl +ipv4(src=2.2.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),dnl +udp(src=0,dst=6081,csum=0x0),geneve(vni=0x7b)),out_port(100)),1 +]) + +dnl Now check that the packet actually has the local_ip in the header. +AT_CHECK([ovs-vsctl -- set Interface p0 options:tx_pcap=p0.pcap]) + +packet=50540000000a5054000000091234 +eth=f8bc124434b6aa55aa5500000800 +ip4=450000320000400040113305020202580101025c +dnl Source port is based on a packet hash, so it may differ depending on the +dnl compiler flags and CPU type. Masked with '....'. +udp=....17c1001e0000 +geneve=0000655800007b00 +encap=${eth}${ip4}${udp}${geneve} +dnl Output to tunnel from a int-br internal port. +dnl Checking that the packet arrived and it was correctly encapsulated. +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}"]) +OVS_WAIT_UNTIL([test $(ovs-pcap p0.pcap | grep -c "${encap}${packet}") -eq 1]) +dnl Sending again to exercise the non-miss upcall path. +AT_CHECK([ovs-appctl netdev-dummy/receive int-br "${packet}"]) +OVS_WAIT_UNTIL([test $(ovs-pcap p0.pcap | grep -c "${encap}${packet}") -eq 2]) + +dnl Finally, checking that the datapath flow also has a local_ip. +AT_CHECK([ovs-appctl dpctl/dump-flows | grep tnl_push \ + | strip_ufid | strip_used], [0], [dnl +recirc_id(0),in_port(2),packet_type(ns=0,id=0),dnl +eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x1234), dnl +packets:1, bytes:14, used:0.0s, dnl +actions:tnl_push(tnl_port(6081),header(size=50,type=5,dnl +eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:00,dl_type=0x0800),dnl +ipv4(src=2.2.2.88,dst=1.1.2.92,proto=17,tos=0,ttl=64,frag=0x4000),dnl +udp(src=0,dst=6081,csum=0x0),geneve(vni=0x7b)),out_port(100)),1 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP + AT_SETUP([tunnel_push_pop - underlay bridge match]) OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 other-config:hwaddr=aa:55:aa:55:00:00]) @@ -796,8 +880,11 @@ dummy@ovs-dummy: hit:0 missed:0 AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local ]) + AT_CHECK([ovs-ofctl add-flow br0 'arp,priority=1,action=normal']) dnl Use arp reply to achieve tunnel next hop mac binding @@ -840,11 +927,12 @@ AT_CHECK([ovs-vsctl add-port int-br t2 dnl -- set Interface t2 type=geneve options:remote_ip=1.1.2.92 dnl options:key=123 ofport_request=2]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 1.1.2.88/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 1.1.2.92/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev br0 SRC 1.1.2.88 local ]) AT_CHECK([ovs-ofctl add-flow br0 action=normal]) @@ -908,10 +996,12 @@ AT_CHECK([ovs-vsctl set port p8 tag=42 dnl -- set port br0 tag=42 dnl -- set port p7 tag=200]) -dnl Set IP address and route for br0. +dnl Set an IP address for br0. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 10.0.0.2/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 10.0.0.11/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2 local ]) dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded @@ -953,10 +1043,12 @@ AT_CHECK([ovs-vsctl add-port ovs-tun0 tun0 dnl -- add-port ovs-tun0 p7 dnl -- set interface p7 type=dummy ofport_request=7]) -dnl Set IP address and route for br0. +dnl Set an IP address for br0. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 10.0.0.2/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 10.0.0.11/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 10.0.0.0/24 dev br0 SRC 10.0.0.2 local ]) dnl Send an ARP reply to port b8 on br0, so that packets will be forwarded @@ -993,3 +1085,81 @@ udp(src=0,dst=4789,csum=0x0),vxlan(flags=0x8000000,vni=0x0)),out_port(100)),8),7 OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([tunnel_push_pop - use non-local port as tunnel endpoint]) + +OVS_VSWITCHD_START([add-port br0 p0 \ + -- set Interface p0 type=dummy ofport_request=1]) + +dnl Adding another port separately to ensure that it gets an +dnl aa:55:aa:55:00:03 MAC address (dummy port number 3). +AT_CHECK([ovs-vsctl add-port br0 vtep0 \ + -- set interface vtep0 type=dummy ofport_request=2]) +AT_CHECK([ovs-vsctl \ + -- add-br int-br \ + -- set bridge int-br datapath_type=dummy \ + -- set Interface int-br ofport_request=3]) +AT_CHECK([ovs-vsctl \ + -- add-port int-br t1 \ + -- set Interface t1 type=gre ofport_request=4 \ + options:remote_ip=1.1.2.92 +]) + +AT_CHECK([ovs-appctl dpif/show], [0], [dnl +dummy@ovs-dummy: hit:0 missed:0 + br0: + br0 65534/100: (dummy-internal) + p0 1/1: (dummy) + vtep0 2/2: (dummy) + int-br: + int-br 65534/3: (dummy-internal) + t1 4/4: (gre: remote_ip=1.1.2.92) +]) + +AT_CHECK([ovs-appctl netdev-dummy/ip4addr vtep0 1.1.2.88/24], [0], [OK +]) +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 1.1.2.0/24 dev vtep0 SRC 1.1.2.88 local +]) + +AT_CHECK([ovs-ofctl add-flow br0 action=normal]) +AT_CHECK([ovs-ofctl add-flow int-br action=normal]) + +dnl Use arp request and reply to achieve tunnel next hop mac binding. +dnl By default, vtep0's MAC address is aa:55:aa:55:00:03. +AT_CHECK([ovs-appctl netdev-dummy/receive vtep0 'recirc_id(0),in_port(2),dnl + eth(dst=ff:ff:ff:ff:ff:ff,src=aa:55:aa:55:00:03),eth_type(0x0806),dnl + arp(tip=1.1.2.92,sip=1.1.2.88,op=1,sha=aa:55:aa:55:00:03,tha=00:00:00:00:00:00)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p0 'recirc_id(0),in_port(1),dnl + eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:03),eth_type(0x0806),dnl + arp(sip=1.1.2.92,tip=1.1.2.88,op=2,sha=f8:bc:12:44:34:b6,tha=aa:55:aa:55:00:03)']) + +AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl +1.1.2.92 f8:bc:12:44:34:b6 br0 +]) + +dnl Check GRE tunnel pop. +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),dnl + eth(src=f8:bc:12:44:34:b6,dst=aa:55:aa:55:00:03),eth_type(0x0800),dnl + ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], +[0], [stdout]) + +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: tnl_pop(4) +]) + +dnl Check GRE tunnel push. +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),dnl + eth(dst=f9:bc:12:44:34:b6,src=af:55:aa:55:00:03),eth_type(0x0800),dnl + ipv4(src=1.1.3.88,dst=1.1.3.92,proto=1,tos=0,ttl=64,frag=no)'], +[0], [stdout]) +AT_CHECK([tail -1 stdout], [0], + [Datapath actions: tnl_push(tnl_port(4),header(size=38,type=3,dnl +eth(dst=f8:bc:12:44:34:b6,src=aa:55:aa:55:00:03,dl_type=0x0800),dnl +ipv4(src=1.1.2.88,dst=1.1.2.92,proto=47,tos=0,ttl=64,frag=0x4000),dnl +gre((flags=0x0,proto=0x6558))),out_port(2)),1 +]) + +OVS_VSWITCHD_STOP +AT_CLEANUP diff --git a/tests/tunnel.at b/tests/tunnel.at index 282651ac73..71e7c2df4e 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at @@ -524,11 +524,12 @@ dummy@ovs-dummy: hit:0 missed:0 v2 3/3: (dummy-internal) ]) -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip4addr br0 172.31.1.1/24], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add 172.31.1.0/24 br0], [0], [OK +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: 172.31.1.0/24 dev br0 SRC 172.31.1.1 local ]) dnl change the flow table to bump the internal table version @@ -1276,15 +1277,12 @@ OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=dummy \ ofport_request=2]) OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP -dnl First setup dummy interface IP address, then add the route -dnl so that tnl-port table can get valid IP address for the device. +dnl Setup dummy interface IP address. AT_CHECK([ovs-appctl netdev-dummy/ip6addr br0 fc00::1/64], [0], [OK ]) -AT_CHECK([ovs-appctl ovs/route/add fc00::0/64 br0], [0], [OK -]) -AT_CHECK([ovs-appctl ovs/route/show], [0], [dnl -Route Table: -User: fc00::/64 dev br0 SRC fc00::1 +dnl Checking that a local route for added IP was successfully installed. +AT_CHECK([ovs-appctl ovs/route/show | grep Cached], [0], [dnl +Cached: fc00::/64 dev br0 SRC fc00::1 local ]) AT_DATA([flows.txt], [dnl diff --git a/utilities/ovs-pki.in b/utilities/ovs-pki.in index e0ba910f94..285018e41e 100755 --- a/utilities/ovs-pki.in +++ b/utilities/ovs-pki.in @@ -57,6 +57,77 @@ FreeBSD|NetBSD|Darwin) ;; esac +case $(uname -s) in +MINGW*|MSYS*) + chmod() + { + local PERM=$1 + local FILE=$2 + local INH= + + if test -d "${FILE}"; then + # Inheritance rules for folders: apply to a folder itself, + # subfolders and files within. + INH='(OI)(CI)' + fi + + case "${PERM}" in + *700 | *600) + # Reset all own and inherited ACEs and grant full access to the + # "Creator Owner". We're giving full access even for 0600, + # because it doesn't matter for a use case of ovs-pki. + icacls "${FILE}" /inheritance:r /grant:r "*S-1-3-0:${INH}F" + ;; + *750) + # Reset all own and inherited ACEs, grant full access to the + # "Creator Owner" and a read+execute access to the "Creator Group". + icacls "${FILE}" /inheritance:r /grant:r \ + "*S-1-3-0:${INH}F" "*S-1-3-1:${INH}RX" + ;; + *) + echo >&2 "Unable to set ${PERM} mode for ${FILE}." + exit 1 + ;; + esac + } + + mkdir() + { + ARG_P= + PERM= + for arg; do + shift + case ${arg} in + -m?*) + PERM=${arg#??} + continue + ;; + -m) + PERM=$1 + shift + continue + ;; + -p) + ARG_P=-p + continue + ;; + *) + set -- "$@" "${arg}" + ;; + esac + done + + command mkdir ${ARG_P} $@ + if [ ${PERM} ]; then + for dir; do + shift + chmod ${PERM} ${dir} + done + fi + } + ;; +esac + for option; do # This option-parsing mechanism borrowed from a Autoconf-generated # configure script under the following license: @@ -466,14 +537,24 @@ CN = $cn [ v3_req ] subjectAltName = DNS:$cn EOF + # It is important to create private keys in $TMP because umask doesn't + # work on Windows and permissions there are inherited from the folder. + # umask itself is still needed though to ensure correct permissions + # on non-Windows platforms. if test $keytype = rsa; then - (umask 077 && openssl genrsa -out "$1-privkey.pem" $bits) 1>&3 2>&3 \ - || exit $? + (umask 077 && openssl genrsa -out "$TMP/privkey.pem" $bits) \ + 1>&3 2>&3 || exit $? else must_exist "$dsaparam" - (umask 077 && openssl gendsa -out "$1-privkey.pem" "$dsaparam") \ + (umask 077 && openssl gendsa -out "$TMP/privkey.pem" "$dsaparam") \ 1>&3 2>&3 || exit $? fi + # Windows: applying permissions (ACEs) to the file itself, just in case. + # 'mv' should technically preserve all the inherited ACEs from a TMP + # folder, but it's better to not rely on that. + chmod 0600 "$TMP/privkey.pem" + mv "$TMP/privkey.pem" "$1-privkey.pem" + openssl req -config "$TMP/req.cnf" -new -text \ -key "$1-privkey.pem" -out "$1-req.pem" 1>&3 2>&3 }