2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 15:25:22 +00:00

openvswitch: Allow external IPsec tunnel management.

OVS GRE IPsec tunnel support has multiple issues, Therefore
it was deprecated in OVS 2.6.

Following patch removes support for GRE IPsec and allows external
IPsec tunnel management for any type of tunnel not just GRE.
e.g. user can encrypt Geneve or VxLan traffic.

It can be done by using openflow pipeline to set skb-mark
and using IPsec keying daemons to implement IPsec tunnels.
This packet can be matched for the skb-mark to encrypt
selective tunnel traffic.

VMware-BZ: 1710701
Signed-off-by: Pravin B Shelar <pshelar@ovn.org>
Acked-by: Ansis Atteka <aatteka@ovn.org>
This commit is contained in:
Pravin B Shelar
2016-09-24 11:44:53 -07:00
parent 5e8bc3c549
commit 2b02d770c4
24 changed files with 23 additions and 1305 deletions

1
NEWS
View File

@@ -25,6 +25,7 @@ Post-v2.6.0
* 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.
v2.6.0 - xx xxx xxxx
---------------------

View File

@@ -30,7 +30,7 @@ vSwitch supports the following features:
* NIC bonding with or without LACP on upstream switch
* NetFlow, sFlow(R), and mirroring for increased visibility
* QoS (Quality of Service) configuration, plus policing
* Geneve, GRE, GRE over IPSEC, VXLAN, and LISP tunneling
* Geneve, GRE, VXLAN, STT, and LISP tunneling
* 802.1ag connectivity fault management
* OpenFlow 1.0 plus numerous extensions
* Transactional configuration database with C and Python bindings

7
debian/automake.mk vendored
View File

@@ -19,9 +19,6 @@ EXTRA_DIST += \
debian/openvswitch-datapath-source.dirs \
debian/openvswitch-datapath-source.install \
debian/openvswitch-dev.install \
debian/openvswitch-ipsec.dirs \
debian/openvswitch-ipsec.init \
debian/openvswitch-ipsec.install \
debian/openvswitch-pki.dirs \
debian/openvswitch-pki.postinst \
debian/openvswitch-pki.postrm \
@@ -71,7 +68,6 @@ EXTRA_DIST += \
debian/ovn-host.postinst \
debian/ovn-host.postrm \
debian/ovn-host.template \
debian/ovs-monitor-ipsec \
debian/python-openvswitch.dirs \
debian/python-openvswitch.install \
debian/rules \
@@ -79,9 +75,6 @@ EXTRA_DIST += \
debian/ifupdown.sh \
debian/source/format
FLAKE8_PYFILES += \
debian/ovs-monitor-ipsec
check-debian-changelog-version:
@DEB_VERSION=`echo '$(VERSION)' | sed 's/pre/~pre/'`; \
if $(FGREP) '($(DEB_VERSION)' $(srcdir)/debian/changelog >/dev/null; \

24
debian/control vendored
View File

@@ -178,30 +178,6 @@ Description: OVN Docker drivers
.
ovn-docker provides the docker drivers for OVN.
Package: openvswitch-ipsec
Architecture: linux-any
Depends: ipsec-tools (>=0.8~alpha20101208),
iproute2,
openvswitch-common (= ${binary:Version}),
openvswitch-switch (= ${binary:Version}),
python,
python-openvswitch (= ${source:Version}),
racoon (>=0.8~alpha20101208),
${misc:Depends},
${shlibs:Depends}
Description: Open vSwitch GRE-over-IPsec support
Open vSwitch is a production quality, multilayer, software-based,
Ethernet virtual switch. It is designed to enable massive network
automation through programmatic extension, while still supporting
standard management interfaces and protocols (e.g. NetFlow, IPFIX,
sFlow, SPAN, RSPAN, CLI, LACP, 802.1ag). In addition, it is designed
to support distribution across multiple physical servers similar to
VMware's vNetwork distributed vswitch or Cisco's Nexus 1000V.
.
The ovs-monitor-ipsec script provides support for encrypting GRE
tunnels with IPsec.
IPsec tunnels support is deprecated.
Package: openvswitch-pki
Architecture: all
Depends: openvswitch-common (<< ${source:Version}.1~),

View File

@@ -1 +0,0 @@
usr/share/openvswitch/scripts

View File

@@ -1,203 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2007, 2009 Javier Fernandez-Sanguino <jfs@debian.org>
#
# This is free software; you may redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2,
# or (at your option) any later version.
#
# This is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License with
# the Debian operating system, in /usr/share/common-licenses/GPL; if
# not, write to the Free Software Foundation, Inc., 59 Temple Place,
# Suite 330, Boston, MA 02111-1307 USA
#
### BEGIN INIT INFO
# Provides: openvswitch-ipsec
# Required-Start: $network $local_fs $remote_fs openvswitch-switch
# Required-Stop: $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Open vSwitch GRE-over-IPsec daemon
# Description: The ovs-monitor-ipsec script provides support for encrypting GRE
# tunnels with IPsec.
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/share/openvswitch/scripts/ovs-monitor-ipsec # Daemon's location
NAME=ovs-monitor-ipsec # Introduce the short server's name here
LOGDIR=/var/log/openvswitch # Log directory to use
PIDFILE=/var/run/openvswitch/$NAME.pid
test -x $DAEMON || exit 0
. /lib/lsb/init-functions
DODTIME=10 # Time to wait for the server to die, in seconds
# If this value is set too low you might not
# let some servers to die gracefully and
# 'restart' will not work
set -e
running_pid() {
# Check if a given process pid's cmdline matches a given name
pid=$1
name=$2
[ -z "$pid" ] && return 1
[ ! -d /proc/$pid ] && return 1
cmd=`cat /proc/$pid/cmdline | tr "\000" " "|cut -d " " -f 2`
# Is this the expected server
[ "$cmd" != "$name" ] && return 1
return 0
}
running() {
# Check if the process is running looking at /proc
# (works for all users)
# No pidfile, probably no daemon present
[ ! -f "$PIDFILE" ] && return 1
pid=`cat $PIDFILE`
running_pid $pid $DAEMON || return 1
return 0
}
uninstall_mark_rule() {
iptables -D INPUT -t mangle $1 -j MARK --set-mark 1/1 || return 0
}
install_mark_rule() {
if ( ! iptables -C INPUT -t mangle $1 -j MARK --set-mark 1/1 2> /dev/null); then
iptables -A INPUT -t mangle $1 -j MARK --set-mark 1/1
fi
}
start_server() {
if [ ! -d /var/run/openvswitch ]; then
install -d -m 755 -o root -g root /var/run/openvswitch
fi
install_mark_rule "-p esp"
install_mark_rule "-p udp --dport 4500"
/usr/share/openvswitch/scripts/ovs-monitor-ipsec \
--pidfile=$PIDFILE --log-file --detach --monitor \
unix:/var/run/openvswitch/db.sock
return 0
}
stop_server() {
if [ -e $PIDFILE ]; then
kill `cat $PIDFILE`
fi
uninstall_mark_rule "-p esp"
uninstall_mark_rule "-p udp --dport 4500"
return 0
}
force_stop() {
# Force the process to die killing it manually
[ ! -e "$PIDFILE" ] && return
if running ; then
kill -15 $pid
# Is it really dead?
sleep "$DODTIME"
if running ; then
kill -9 $pid
sleep "$DODTIME"
if running ; then
echo "Cannot kill $NAME (pid=$pid)!"
exit 1
fi
fi
fi
rm -f $PIDFILE
}
case "$1" in
start)
log_daemon_msg "Starting $NAME"
# Check if it's running first
if running ; then
log_progress_msg "apparently already running"
log_end_msg 0
exit 0
fi
if start_server && running ; then
# It's ok, the server started and is running
log_end_msg 0
else
# Either we could not start it or it is not running
# after we did
# NOTE: Some servers might die some time after they start,
# this code does not try to detect this and might give
# a false positive (use 'status' for that)
log_end_msg 1
fi
;;
stop)
log_daemon_msg "Stopping $NAME"
if running ; then
# Only stop the server if we see it running
stop_server
log_end_msg $?
else
# If it's not running don't do anything
log_progress_msg "apparently not running"
log_end_msg 0
exit 0
fi
;;
force-stop)
# First try to stop gracefully the program
$0 stop
if running; then
# If it's still running try to kill it more forcefully
log_daemon_msg "Stopping (force) $NAME"
force_stop
log_end_msg $?
fi
;;
restart|force-reload)
log_daemon_msg "Restarting $NAME"
stop_server
# Wait some sensible amount, some server need this
[ -n "$DODTIME" ] && sleep $DODTIME
start_server
running
log_end_msg $?
;;
status)
log_daemon_msg "Checking status of $NAME"
if running ; then
log_progress_msg "running"
log_end_msg 0
else
log_progress_msg "apparently not running"
log_end_msg 1
exit 1
fi
;;
# Use this if the daemon cannot reload
reload)
log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon"
log_warning_msg "cannot re-read the config file (use restart)."
;;
*)
N=/etc/init.d/openvswitch-ipsec
echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0

View File

@@ -1 +0,0 @@
debian/ovs-monitor-ipsec usr/share/openvswitch/scripts

View File

@@ -1,507 +0,0 @@
#! /usr/bin/env python
# Copyright (c) 2009, 2010, 2011, 2012 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.
# A daemon to monitor attempts to create GRE-over-IPsec tunnels.
# Uses racoon and setkey to support the configuration. Assumes that
# OVS has complete control over IPsec configuration for the box.
# xxx To-do:
# - Doesn't actually check that Interface is connected to bridge
# - If a certificate is badly formed, Racoon will refuse to start. We
# should do a better job of verifying certificates are valid before
# adding an interface to racoon.conf.
import argparse
import glob
import os
import subprocess
import sys
import ovs.dirs
from ovs.db import error
import ovs.util
import ovs.daemon
import ovs.db.idl
import ovs.unixctl
import ovs.unixctl.server
import ovs.vlog
from six.moves import range
import six
vlog = ovs.vlog.Vlog("ovs-monitor-ipsec")
root_prefix = '' # Prefix for absolute file names, for testing.
SETKEY = "/usr/sbin/setkey"
IP = "/sbin/ip"
exiting = False
IPSEC_MARK = "1"
def unixctl_exit(conn, unused_argv, unused_aux):
global exiting
exiting = True
conn.reply(None)
# Class to configure the racoon daemon, which handles IKE negotiation
class Racoon(object):
# Default locations for files
conf_file = "/etc/racoon/racoon.conf"
cert_dir = "/etc/racoon/certs"
psk_file = "/etc/racoon/psk.txt"
# Racoon configuration header we use for IKE
conf_header = """# Configuration file generated by Open vSwitch
#
# Do not modify by hand!
path pre_shared_key "%s";
path certificate "%s";
"""
# Racoon configuration footer we use for IKE
conf_footer = """sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
"""
# Certificate entry template.
cert_entry = """remote %s {
exchange_mode main;
nat_traversal on;
ike_frag on;
certificate_type x509 "%s" "%s";
my_identifier asn1dn;
peers_identifier asn1dn;
peers_certfile x509 "%s";
verify_identifier on;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method rsasig;
dh_group 2;
}
}
"""
# Pre-shared key template.
psk_entry = """remote %s {
exchange_mode main;
nat_traversal on;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
"""
def __init__(self):
self.psk_hosts = {}
self.cert_hosts = {}
if not os.path.isdir(root_prefix + self.cert_dir):
os.mkdir(self.cert_dir)
# Clean out stale peer certs from previous runs
for ovs_cert in glob.glob("%s%s/ovs-*.pem"
% (root_prefix, self.cert_dir)):
try:
os.remove(ovs_cert)
except OSError:
vlog.warn("couldn't remove %s" % ovs_cert)
# Replace racoon's conf file with our template
self.commit()
def reload(self):
exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon",
"reload"])
if exitcode != 0:
# Racoon is finicky about its configuration file and will
# refuse to start if it sees something it doesn't like
# (e.g., a certificate file doesn't exist). Try restarting
# the process before giving up.
vlog.warn("attempting to restart racoon")
exitcode = subprocess.call([root_prefix + "/etc/init.d/racoon",
"restart"])
if exitcode != 0:
vlog.warn("couldn't reload racoon")
def commit(self):
# Rewrite the Racoon configuration file
conf_file = open(root_prefix + self.conf_file, 'w')
conf_file.write(Racoon.conf_header % (self.psk_file, self.cert_dir))
for host, vals in six.iteritems(self.cert_hosts):
conf_file.write(Racoon.cert_entry % (host, vals["certificate"],
vals["private_key"], vals["peer_cert_file"]))
for host in self.psk_hosts:
conf_file.write(Racoon.psk_entry % host)
conf_file.write(Racoon.conf_footer)
conf_file.close()
# Rewrite the pre-shared keys file; it must only be readable by root.
orig_umask = os.umask(0o077)
psk_file = open(root_prefix + Racoon.psk_file, 'w')
os.umask(orig_umask)
psk_file.write("# Generated by Open vSwitch...do not modify by hand!")
psk_file.write("\n\n")
for host, vals in six.iteritems(self.psk_hosts):
psk_file.write("%s %s\n" % (host, vals["psk"]))
psk_file.close()
self.reload()
def _add_psk(self, host, psk):
if host in self.cert_hosts:
raise error.Error("host %s already defined for cert" % host)
self.psk_hosts[host] = psk
self.commit()
def _verify_certs(self, vals):
# Racoon will refuse to start if the certificate files don't
# exist, so verify that they're there.
if not os.path.isfile(root_prefix + vals["certificate"]):
raise error.Error("'certificate' file does not exist: %s"
% vals["certificate"])
elif not os.path.isfile(root_prefix + vals["private_key"]):
raise error.Error("'private_key' file does not exist: %s"
% vals["private_key"])
# Racoon won't start if a given certificate or private key isn't
# valid. This is a weak test, but will detect the most flagrant
# errors.
if vals["peer_cert"].find("-----BEGIN CERTIFICATE-----") == -1:
raise error.Error("'peer_cert' is not in valid PEM format")
cert = open(root_prefix + vals["certificate"]).read()
if cert.find("-----BEGIN CERTIFICATE-----") == -1:
raise error.Error("'certificate' is not in valid PEM format")
cert = open(root_prefix + vals["private_key"]).read()
if cert.find("-----BEGIN RSA PRIVATE KEY-----") == -1:
raise error.Error("'private_key' is not in valid PEM format")
def _add_cert(self, host, vals):
if host in self.psk_hosts:
raise error.Error("host %s already defined for psk" % host)
if vals["certificate"] is None:
raise error.Error("'certificate' not defined for %s" % host)
elif vals["private_key"] is None:
# Assume the private key is stored in the same PEM file as
# the certificate. We make a copy of "vals" so that we don't
# modify the original "vals", which would cause the script
# to constantly think that the configuration has changed
# in the database.
vals = vals.copy()
vals["private_key"] = vals["certificate"]
self._verify_certs(vals)
# The peer's certificate comes to us in PEM format as a string.
# Write that string to a file for Racoon to use.
f = open(root_prefix + vals["peer_cert_file"], "w")
f.write(vals["peer_cert"])
f.close()
self.cert_hosts[host] = vals
self.commit()
def _del_cert(self, host):
peer_cert_file = self.cert_hosts[host]["peer_cert_file"]
del self.cert_hosts[host]
self.commit()
try:
os.remove(root_prefix + peer_cert_file)
except OSError:
pass
def add_entry(self, host, vals):
if vals["peer_cert"]:
self._add_cert(host, vals)
elif vals["psk"]:
self._add_psk(host, vals)
def del_entry(self, host):
if host in self.cert_hosts:
self._del_cert(host)
elif host in self.psk_hosts:
del self.psk_hosts[host]
self.commit()
# Class to configure IPsec on a system using racoon for IKE and setkey
# for maintaining the Security Association Database (SAD) and Security
# Policy Database (SPD). Only policies for GRE are supported.
class IPsec(object):
def __init__(self):
self.sad_flush()
self.spd_flush()
self.racoon = Racoon()
self.entries = []
def call_setkey(self, cmds):
try:
p = subprocess.Popen([root_prefix + SETKEY, "-c"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
except:
vlog.err("could not call %s%s" % (root_prefix, SETKEY))
sys.exit(1)
# xxx It is safer to pass the string into the communicate()
# xxx method, but it didn't work for slightly longer commands.
# xxx An alternative may need to be found.
p.stdin.write(cmds)
return p.communicate()[0]
def call_ip_xfrm(self, cmds):
exitcode = subprocess.call([root_prefix + IP, "xfrm"] + cmds)
if exitcode != 0:
vlog.err("couldn't install IPsec policy that prevents "
"traffic from exiting unencrypted")
def get_spi(self, local_ip, remote_ip, proto="esp"):
# Run the setkey dump command to retrieve the SAD. Then, parse
# the output looking for SPI buried in the output. Note that
# multiple SAD entries can exist for the same "flow", since an
# older entry could be in a "dying" state.
spi_list = []
host_line = "%s %s" % (local_ip, remote_ip)
results = self.call_setkey("dump ;\n").split("\n")
for i in range(len(results)):
if results[i].strip() == host_line:
# The SPI is in the line following the host pair
spi_line = results[i + 1]
if (spi_line[1:4] == proto):
spi = spi_line.split()[2]
spi_list.append(spi.split('(')[1].rstrip(')'))
return spi_list
def sad_flush(self):
self.call_setkey("flush;\n")
def sad_del(self, local_ip, remote_ip):
# To delete all SAD entries, we should be able to use setkey's
# "deleteall" command. Unfortunately, it's fundamentally broken
# on Linux and not documented as such.
cmds = ""
# Delete local_ip->remote_ip SAD entries
spi_list = self.get_spi(local_ip, remote_ip)
for spi in spi_list:
cmds += "delete %s %s esp %s;\n" % (local_ip, remote_ip, spi)
# Delete remote_ip->local_ip SAD entries
spi_list = self.get_spi(remote_ip, local_ip)
for spi in spi_list:
cmds += "delete %s %s esp %s;\n" % (remote_ip, local_ip, spi)
if cmds:
self.call_setkey(cmds)
def spd_flush(self):
self.call_setkey("spdflush;\n")
self.call_ip_xfrm(["policy", "add", "src", "0.0.0.0/0", "dst",
"0.0.0.0/0", "proto", "gre", "dir", "out",
"mark", IPSEC_MARK, "mask", IPSEC_MARK,
"action", "block", "priority", "4294967295"])
def spd_add(self, local_ip, remote_ip):
cmds = ("spdadd %s %s gre -P out ipsec esp/transport//require;\n" %
(local_ip, remote_ip))
cmds += ("spdadd %s %s gre -P in ipsec esp/transport//require;\n" %
(remote_ip, local_ip))
self.call_setkey(cmds)
def spd_del(self, local_ip, remote_ip):
cmds = "spddelete %s %s gre -P out;\n" % (local_ip, remote_ip)
cmds += "spddelete %s %s gre -P in;\n" % (remote_ip, local_ip)
self.call_setkey(cmds)
def add_entry(self, local_ip, remote_ip, vals):
if remote_ip in self.entries:
raise error.Error("host %s already configured for ipsec"
% remote_ip)
self.racoon.add_entry(remote_ip, vals)
self.spd_add(local_ip, remote_ip)
self.entries.append(remote_ip)
def del_entry(self, local_ip, remote_ip):
if remote_ip in self.entries:
self.racoon.del_entry(remote_ip)
self.spd_del(local_ip, remote_ip)
self.sad_del(local_ip, remote_ip)
self.entries.remove(remote_ip)
def update_ipsec(ipsec, interfaces, new_interfaces):
for name, vals in six.iteritems(interfaces):
if name not in new_interfaces:
ipsec.del_entry(vals["local_ip"], vals["remote_ip"])
for name, vals in six.iteritems(new_interfaces):
orig_vals = interfaces.get(name)
if orig_vals:
# Configuration for this host already exists. Check if it's
# changed. We use set difference, since we want to ignore
# any local additions to "orig_vals" that we've made
# (e.g. the "peer_cert_file" key).
if set(vals.items()) - set(orig_vals.items()):
ipsec.del_entry(vals["local_ip"], vals["remote_ip"])
else:
continue
try:
ipsec.add_entry(vals["local_ip"], vals["remote_ip"], vals)
except error.Error as msg:
vlog.warn("skipping ipsec config for %s: %s" % (name, msg))
def get_ssl_cert(data):
for ovs_rec in data["Open_vSwitch"].rows.values():
if ovs_rec.ssl:
ssl = ovs_rec.ssl[0]
if ssl.certificate and ssl.private_key:
return (ssl.certificate, ssl.private_key)
return None
def main():
parser = argparse.ArgumentParser()
parser.add_argument("database", metavar="DATABASE",
help="A socket on which ovsdb-server is listening.")
parser.add_argument("--root-prefix", metavar="DIR",
help="Use DIR as alternate root directory"
" (for testing).")
ovs.vlog.add_args(parser)
ovs.daemon.add_args(parser)
args = parser.parse_args()
ovs.vlog.handle_args(args)
ovs.daemon.handle_args(args)
global root_prefix
if args.root_prefix:
root_prefix = args.root_prefix
remote = args.database
schema_helper = ovs.db.idl.SchemaHelper()
schema_helper.register_columns("Interface", ["name", "type", "options"])
schema_helper.register_columns("Open_vSwitch", ["ssl"])
schema_helper.register_columns("SSL", ["certificate", "private_key"])
idl = ovs.db.idl.Idl(remote, schema_helper)
ipsec = IPsec()
ovs.daemon.daemonize()
ovs.unixctl.command_register("exit", "", 0, 0, unixctl_exit, None)
error, unixctl_server = ovs.unixctl.server.UnixctlServer.create(None)
if error:
ovs.util.ovs_fatal(error, "could not create unixctl server", vlog)
interfaces = {}
seqno = idl.change_seqno # Sequence number when we last processed the db
while True:
unixctl_server.run()
if exiting:
break
idl.run()
if seqno == idl.change_seqno:
poller = ovs.poller.Poller()
unixctl_server.wait(poller)
idl.wait(poller)
poller.block()
continue
seqno = idl.change_seqno
ssl_cert = get_ssl_cert(idl.tables)
new_interfaces = {}
for rec in six.itervalues(idl.tables["Interface"].rows):
if rec.type == "ipsec_gre":
name = rec.name
options = rec.options
peer_cert_name = "ovs-%s.pem" % (options.get("remote_ip"))
entry = {
"remote_ip": options.get("remote_ip"),
"local_ip": options.get("local_ip", "0.0.0.0/0"),
"certificate": options.get("certificate"),
"private_key": options.get("private_key"),
"use_ssl_cert": options.get("use_ssl_cert"),
"peer_cert": options.get("peer_cert"),
"peer_cert_file": Racoon.cert_dir + "/" + peer_cert_name,
"psk": options.get("psk")}
if entry["peer_cert"] and entry["psk"]:
vlog.warn("both 'peer_cert' and 'psk' defined for %s"
% name)
continue
elif not entry["peer_cert"] and not entry["psk"]:
vlog.warn("no 'peer_cert' or 'psk' defined for %s" % name)
continue
# The "use_ssl_cert" option is deprecated and will
# likely go away in the near future.
if entry["use_ssl_cert"] == "true":
if not ssl_cert:
vlog.warn("no valid SSL entry for %s" % name)
continue
entry["certificate"] = ssl_cert[0]
entry["private_key"] = ssl_cert[1]
new_interfaces[name] = entry
if interfaces != new_interfaces:
update_ipsec(ipsec, interfaces, new_interfaces)
interfaces = new_interfaces
unixctl_server.close()
idl.close()
if __name__ == '__main__':
try:
main()
except SystemExit:
# Let system.exit() calls complete normally
raise
except:
vlog.exception("traceback")
sys.exit(ovs.daemon.RESTART_EXIT_CODE)

View File

@@ -402,14 +402,13 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
struct netdev_vport *dev = netdev_vport_cast(dev_);
const char *name = netdev_get_name(dev_);
const char *type = netdev_get_type(dev_);
bool ipsec_mech_set, needs_dst_port, has_csum;
bool needs_dst_port, has_csum;
uint16_t dst_proto = 0, src_proto = 0;
struct netdev_tunnel_config tnl_cfg;
struct smap_node *node;
has_csum = strstr(type, "gre") || strstr(type, "geneve") ||
strstr(type, "stt") || strstr(type, "vxlan");
ipsec_mech_set = false;
memset(&tnl_cfg, 0, sizeof tnl_cfg);
/* Add a default destination port for tunnel ports if none specified. */
@@ -430,7 +429,6 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
}
needs_dst_port = netdev_vport_needs_dst_port(dev_);
tnl_cfg.ipsec = strstr(type, "ipsec");
tnl_cfg.dont_fragment = true;
SMAP_FOR_EACH (node, args) {
@@ -485,33 +483,6 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
if (!strcmp(node->value, "false")) {
tnl_cfg.dont_fragment = false;
}
} else if (!strcmp(node->key, "peer_cert") && tnl_cfg.ipsec) {
if (smap_get(args, "certificate")) {
ipsec_mech_set = true;
} else {
const char *use_ssl_cert;
/* If the "use_ssl_cert" is true, then "certificate" and
* "private_key" will be pulled from the SSL table. The
* use of this option is strongly discouraged, since it
* will like be removed when multiple SSL configurations
* are supported by OVS.
*/
use_ssl_cert = smap_get(args, "use_ssl_cert");
if (!use_ssl_cert || strcmp(use_ssl_cert, "true")) {
VLOG_ERR("%s: 'peer_cert' requires 'certificate' argument",
name);
return EINVAL;
}
ipsec_mech_set = true;
}
} else if (!strcmp(node->key, "psk") && tnl_cfg.ipsec) {
ipsec_mech_set = true;
} else if (tnl_cfg.ipsec
&& (!strcmp(node->key, "certificate")
|| !strcmp(node->key, "private_key")
|| !strcmp(node->key, "use_ssl_cert"))) {
/* Ignore options not used by the netdev. */
} else if (!strcmp(node->key, "key") ||
!strcmp(node->key, "in_key") ||
!strcmp(node->key, "out_key")) {
@@ -539,41 +510,6 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args)
}
}
if (tnl_cfg.ipsec) {
static struct ovs_mutex mutex = OVS_MUTEX_INITIALIZER;
static pid_t pid = 0;
VLOG_ERR("%s: OVS IPsec tunnel support is deprecated.", name);
#ifndef _WIN32
ovs_mutex_lock(&mutex);
if (pid <= 0) {
char *file_name = xasprintf("%s/%s", ovs_rundir(),
"ovs-monitor-ipsec.pid");
pid = read_pidfile(file_name);
free(file_name);
}
ovs_mutex_unlock(&mutex);
#endif
if (pid < 0) {
VLOG_ERR("%s: IPsec requires the ovs-monitor-ipsec daemon",
name);
return EINVAL;
}
if (smap_get(args, "peer_cert") && smap_get(args, "psk")) {
VLOG_ERR("%s: cannot define both 'peer_cert' and 'psk'", name);
return EINVAL;
}
if (!ipsec_mech_set) {
VLOG_ERR("%s: IPsec requires an 'peer_cert' or psk' argument",
name);
return EINVAL;
}
}
if (!ipv6_addr_is_set(&tnl_cfg.ipv6_dst) && !tnl_cfg.ip_dst_flow) {
VLOG_ERR("%s: %s type requires valid 'remote_ip' argument",
name, type);
@@ -898,7 +834,6 @@ netdev_vport_tunnel_register(void)
TUNNEL_CLASS("gre", "gre_sys", netdev_gre_build_header,
netdev_gre_push_header,
netdev_gre_pop_header),
TUNNEL_CLASS("ipsec_gre", "gre_sys", NULL, NULL, NULL),
TUNNEL_CLASS("vxlan", "vxlan_sys", netdev_vxlan_build_header,
netdev_tnl_push_udp_header,
netdev_vxlan_pop_header),

View File

@@ -97,7 +97,6 @@ struct netdev_tunnel_config {
bool tos_inherit;
bool csum;
bool ipsec;
bool dont_fragment;
};

View File

@@ -78,7 +78,6 @@ enum dpif_ipfix_tunnel_type {
DPIF_IPFIX_TUNNEL_GRE = 0x02,
DPIF_IPFIX_TUNNEL_LISP = 0x03,
DPIF_IPFIX_TUNNEL_STT = 0x04,
DPIF_IPFIX_TUNNEL_IPSEC_GRE = 0x05,
DPIF_IPFIX_TUNNEL_GENEVE = 0x07,
NUM_DPIF_IPFIX_TUNNEL
};
@@ -311,16 +310,12 @@ struct ipfix_data_record_flow_key_icmp {
});
BUILD_ASSERT_DECL(sizeof(struct ipfix_data_record_flow_key_icmp) == 2);
/* For the tunnel type that is on the top of IPSec, the protocol identifier
* of the upper tunnel type is used.
*/
static uint8_t tunnel_protocol[NUM_DPIF_IPFIX_TUNNEL] = {
0, /* reserved */
IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_VXLAN */
IPPROTO_GRE, /* DPIF_IPFIX_TUNNEL_GRE */
IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_LISP*/
IPPROTO_TCP, /* DPIF_IPFIX_TUNNEL_STT*/
IPPROTO_GRE, /* DPIF_IPFIX_TUNNEL_IPSEC_GRE */
0 , /* reserved */
IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_GENEVE*/
};
@@ -657,10 +652,6 @@ dpif_ipfix_add_tunnel_port(struct dpif_ipfix *di, struct ofport *ofport,
/* 32-bit key gre */
dip->tunnel_type = DPIF_IPFIX_TUNNEL_GRE;
dip->tunnel_key_length = 4;
} else if (strcmp(type, "ipsec_gre") == 0) {
/* 32-bit key ipsec_gre */
dip->tunnel_type = DPIF_IPFIX_TUNNEL_IPSEC_GRE;
dip->tunnel_key_length = 4;
} else if (strcmp(type, "vxlan") == 0) {
dip->tunnel_type = DPIF_IPFIX_TUNNEL_VXLAN;
dip->tunnel_key_length = 3;
@@ -1728,12 +1719,6 @@ ipfix_cache_entry_init(struct ipfix_flow_cache_entry *entry,
data_tunnel->tunnel_destination_ipv4_address = tunnel_key->ip_dst;
/* The tunnel_protocol_identifier is from tunnel_proto array, which
* contains protocol_identifiers of each tunnel type.
* For the tunnel type on the top of IPSec, which uses the protocol
* identifier of the upper tunnel type is used, the tcp_src and tcp_dst
* are decided based on the protocol identifiers.
* E.g:
* The protocol identifier of DPIF_IPFIX_TUNNEL_IPSEC_GRE is IPPROTO_GRE,
* and both tp_src and tp_dst are zero.
*/
data_tunnel->tunnel_protocol_identifier =
tunnel_protocol[tunnel_port->tunnel_type];

View File

@@ -61,7 +61,6 @@ enum dpif_sflow_tunnel_type {
DPIF_SFLOW_TUNNEL_VXLAN,
DPIF_SFLOW_TUNNEL_GRE,
DPIF_SFLOW_TUNNEL_LISP,
DPIF_SFLOW_TUNNEL_IPSEC_GRE,
DPIF_SFLOW_TUNNEL_GENEVE
};
@@ -582,8 +581,6 @@ dpif_sflow_tunnel_type(struct ofport *ofport) {
if (type) {
if (strcmp(type, "gre") == 0) {
return DPIF_SFLOW_TUNNEL_GRE;
} else if (strcmp(type, "ipsec_gre") == 0) {
return DPIF_SFLOW_TUNNEL_IPSEC_GRE;
} else if (strcmp(type, "vxlan") == 0) {
return DPIF_SFLOW_TUNNEL_VXLAN;
} else if (strcmp(type, "lisp") == 0) {
@@ -606,10 +603,6 @@ dpif_sflow_tunnel_proto(enum dpif_sflow_tunnel_type tunnel_type)
ipproto = IPPROTO_GRE;
break;
case DPIF_SFLOW_TUNNEL_IPSEC_GRE:
ipproto = IPPROTO_ESP;
break;
case DPIF_SFLOW_TUNNEL_VXLAN:
case DPIF_SFLOW_TUNNEL_LISP:
case DPIF_SFLOW_TUNNEL_GENEVE:

View File

@@ -41,15 +41,11 @@
VLOG_DEFINE_THIS_MODULE(tunnel);
/* skb mark used for IPsec tunnel packets */
#define IPSEC_MARK 1
struct tnl_match {
ovs_be64 in_key;
struct in6_addr ipv6_src;
struct in6_addr ipv6_dst;
odp_port_t odp_port;
uint32_t pkt_mark;
bool in_key_flow;
bool ip_src_flow;
bool ip_dst_flow;
@@ -164,7 +160,6 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev,
tnl_port->match.ipv6_dst = cfg->ipv6_dst;
tnl_port->match.ip_src_flow = cfg->ip_src_flow;
tnl_port->match.ip_dst_flow = cfg->ip_dst_flow;
tnl_port->match.pkt_mark = cfg->ipsec ? IPSEC_MARK : 0;
tnl_port->match.in_key_flow = cfg->in_key_flow;
tnl_port->match.odp_port = odp_port;
@@ -357,7 +352,6 @@ tnl_process_ecn(struct flow *flow)
flow->nw_tos |= IP_ECN_CE;
}
flow->pkt_mark &= ~IPSEC_MARK;
return true;
}
@@ -383,8 +377,6 @@ tnl_wc_init(struct flow *flow, struct flow_wildcards *wc)
wc->masks.tunnel.tp_src = 0;
wc->masks.tunnel.tp_dst = 0;
memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark);
if (is_ip_any(flow)
&& IP_ECN_is_ce(flow->tunnel.ip_tos)) {
wc->masks.nw_tos |= IP_ECN_MASK;
@@ -435,9 +427,6 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
flow->tunnel.ipv6_dst = in6addr_any;
}
}
flow->pkt_mark |= tnl_port->match.pkt_mark;
wc->masks.pkt_mark |= tnl_port->match.pkt_mark;
if (!cfg->out_key_flow) {
flow->tunnel.tun_id = cfg->out_key;
}
@@ -561,7 +550,6 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
match.ipv6_dst = flow_tnl_src(&flow->tunnel);
}
match.odp_port = flow->in_port.odp_port;
match.pkt_mark = flow->pkt_mark;
match.in_key_flow = in_key_flow;
match.ip_dst_flow = ip_dst_flow;
match.ip_src_flow = ip_src == IP_SRC_FLOW;
@@ -616,7 +604,6 @@ tnl_match_fmt(const struct tnl_match *match, struct ds *ds)
}
ds_put_format(ds, ", dp port=%"PRIu32, match->odp_port);
ds_put_format(ds, ", pkt mark=%"PRIu32, match->pkt_mark);
}
static void

View File

@@ -82,7 +82,6 @@ TESTSUITE_AT = \
tests/ovsdb-idl.at \
tests/ovsdb-lock.at \
tests/ovs-vsctl.at \
tests/ovs-monitor-ipsec.at \
tests/ovs-xapi-sync.at \
tests/stp.at \
tests/rstp.at \

View File

@@ -370,7 +370,6 @@ check_logs () {
done
sed -n "$1
/.*OVS IPsec tunnel support is deprecated./d
/timeval.*Unreasonably long [[0-9]]*ms poll interval/d
/timeval.*faults: [[0-9]]* minor, [[0-9]]* major/d
/timeval.*disk: [[0-9]]* reads, [[0-9]]* writes/d
@@ -469,53 +468,4 @@ m4_define([WAIT_FOR_DUMMY_PORTS], \
OVS_WAIT_WHILE([ovs-appctl netdev-dummy/conn-state dummy_port \
| grep 'unknown\|disconnected'])])])
# OVS_MONITOR_IPSEC_START()
#
# Starts ovs-monitor-ipsec daemon. Use this macro only after testing
# that python is present on the system.
m4_define([OVS_MONITOR_IPSEC_START],
[
cp "$top_srcdir/vswitchd/vswitch.ovsschema" .
on_exit 'kill `cat pid ovs-monitor-ipsec.pid`'
mkdir etc etc/init.d etc/racoon etc/racoon/certs
mkdir usr usr/sbin
mkdir sbin
AT_DATA([etc/init.d/racoon], [dnl
#! /bin/sh
echo "racoon: @S|@@" >&3
exit 0
])
chmod +x etc/init.d/racoon
AT_DATA([usr/sbin/setkey], [dnl
#! /bin/sh
exec >&3
echo "setkey:"
while read line; do
echo "> $line"
done
])
chmod +x usr/sbin/setkey
AT_DATA([sbin/ip], [dnl
#! /bin/sh
exit 0
])
chmod +x sbin/ip
touch etc/racoon/certs/ovs-stale.pem
###
### Start ovs-monitor-ipsec and wait for it to delete the stale cert.
###
AT_CHECK(
[$PYTHON $top_srcdir/debian/ovs-monitor-ipsec "--root-prefix=`pwd`" \
"--pidfile=`pwd`/ovs-monitor-ipsec.pid" \
unix:$OVS_RUNDIR/db.sock 2>log 3>actions &])
AT_CAPTURE_FILE([log])
AT_CAPTURE_FILE([actions])
OVS_WAIT_UNTIL([test ! -f etc/racoon/certs/ovs-stale.pem])
])

View File

@@ -195,7 +195,7 @@ OVS_WAIT_UNTIL([check_datapath_type ""])
# The following will need to be updated as OVS starts to support more
# interface types.
expected_iface_types="dummy,dummy-internal,dummy-pmd,geneve,gre,internal,ipsec_gre,lisp,patch,stt,system,tap,vxlan"
expected_iface_types="dummy,dummy-internal,dummy-pmd,geneve,gre,internal,lisp,patch,stt,system,tap,vxlan"
chassis_iface_types=$(ovn-sbctl get Chassis ${sysid} external_ids:iface-types | sed -e 's/\"//g')
echo "chassis_iface_types = ${chassis_iface_types}"
AT_CHECK([test "${expected_iface_types}" = "${chassis_iface_types}"])

View File

@@ -1,271 +0,0 @@
AT_BANNER([ovs-monitor-ipsec])
AT_SETUP([ovs-monitor-ipsec])
AT_SKIP_IF([test $HAVE_PYTHON = no])
AT_SKIP_IF([test "$IS_WIN32" = "yes"])
AT_SKIP_IF([$non_ascii_cwd])
trim () { # Removes blank lines and lines starting with # from input.
sed -e '/^#/d' -e '/^[ ]*$/d' "$@"
}
OVS_VSWITCHD_START([])
OVS_MONITOR_IPSEC_START
###
### Add an ipsec_gre psk interface and check what ovs-monitor-ipsec does
###
AT_CHECK([ovs-vsctl \
-- add-port br0 gre0 \
-- set interface gre0 type=ipsec_gre \
options:remote_ip=1.2.3.4 \
options:psk=swordfish])
OVS_WAIT_UNTIL([test -f actions && grep 'spdadd 1.2.3.4' actions >/dev/null])
AT_CHECK([cat actions], [0], [dnl
setkey:
> flush;
setkey:
> spdflush;
racoon: reload
racoon: reload
setkey:
> spdadd 0.0.0.0/0 1.2.3.4 gre -P out ipsec esp/transport//require;
> spdadd 1.2.3.4 0.0.0.0/0 gre -P in ipsec esp/transport//require;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [1.2.3.4 swordfish
])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
remote 1.2.3.4 {
exchange_mode main;
nat_traversal on;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method pre_shared_key;
dh_group 2;
}
}
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
###
### Delete the ipsec_gre interface and check what ovs-monitor-ipsec does
###
AT_CHECK([ovs-vsctl del-port gre0])
OVS_WAIT_UNTIL([test `wc -l < actions` -ge 17])
AT_CHECK([sed '1,9d' actions], [0], [dnl
racoon: reload
setkey:
> spddelete 0.0.0.0/0 1.2.3.4 gre -P out;
> spddelete 1.2.3.4 0.0.0.0/0 gre -P in;
setkey:
> dump ;
setkey:
> dump ;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
###
### Add ipsec_gre certificate interface and check what ovs-monitor-ipsec does
###
AT_DATA([cert.pem], [dnl
-----BEGIN CERTIFICATE-----
(not a real certificate)
-----END CERTIFICATE-----
])
AT_DATA([key.pem], [dnl
-----BEGIN RSA PRIVATE KEY-----
(not a real private key)
-----END RSA PRIVATE KEY-----
])
AT_CHECK([ovs-vsctl \
-- add-port br0 gre1 \
-- set Interface gre1 type=ipsec_gre \
options:remote_ip=2.3.4.5 \
options:peer_cert='"-----BEGIN CERTIFICATE-----
(not a real peer certificate)
-----END CERTIFICATE-----
"' \
options:certificate='"/cert.pem"' \
options:private_key='"/key.pem"'])
OVS_WAIT_UNTIL([test `wc -l < actions` -ge 21])
AT_CHECK([sed '1,17d' actions], [0], [dnl
racoon: reload
setkey:
> spdadd 0.0.0.0/0 2.3.4.5 gre -P out ipsec esp/transport//require;
> spdadd 2.3.4.5 0.0.0.0/0 gre -P in ipsec esp/transport//require;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
remote 2.3.4.5 {
exchange_mode main;
nat_traversal on;
ike_frag on;
certificate_type x509 "/cert.pem" "/key.pem";
my_identifier asn1dn;
peers_identifier asn1dn;
peers_certfile x509 "/etc/racoon/certs/ovs-2.3.4.5.pem";
verify_identifier on;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method rsasig;
dh_group 2;
}
}
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
AT_CHECK([cat etc/racoon/certs/ovs-2.3.4.5.pem], [0], [dnl
-----BEGIN CERTIFICATE-----
(not a real peer certificate)
-----END CERTIFICATE-----
])
###
### Delete the ipsec_gre certificate interface.
###
AT_CHECK([ovs-vsctl del-port gre1])
OVS_WAIT_UNTIL([test `wc -l < actions` -ge 29])
AT_CHECK([sed '1,21d' actions], [0], [dnl
racoon: reload
setkey:
> spddelete 0.0.0.0/0 2.3.4.5 gre -P out;
> spddelete 2.3.4.5 0.0.0.0/0 gre -P in;
setkey:
> dump ;
setkey:
> dump ;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
AT_CHECK([test ! -f etc/racoon/certs/ovs-2.3.4.5.pem])
###
### Add an SSL certificate interface.
###
cp cert.pem ssl-cert.pem
cp key.pem ssl-key.pem
AT_DATA([ssl-cacert.pem], [dnl
-----BEGIN CERTIFICATE-----
(not a real CA certificate)
-----END CERTIFICATE-----
])
AT_CHECK([ovs-vsctl set-ssl /ssl-key.pem /ssl-cert.pem /ssl-cacert.pem \
-- add-port br0 gre2 \
-- set Interface gre2 type=ipsec_gre \
options:remote_ip=3.4.5.6 \
options:peer_cert='"-----BEGIN CERTIFICATE-----
(not a real peer certificate)
-----END CERTIFICATE-----
"' \
options:use_ssl_cert='"true"'])
OVS_WAIT_UNTIL([test `wc -l < actions` -ge 33])
AT_CHECK([sed '1,29d' actions], [0], [dnl
racoon: reload
setkey:
> spdadd 0.0.0.0/0 3.4.5.6 gre -P out ipsec esp/transport//require;
> spdadd 3.4.5.6 0.0.0.0/0 gre -P in ipsec esp/transport//require;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
remote 3.4.5.6 {
exchange_mode main;
nat_traversal on;
ike_frag on;
certificate_type x509 "/ssl-cert.pem" "/ssl-key.pem";
my_identifier asn1dn;
peers_identifier asn1dn;
peers_certfile x509 "/etc/racoon/certs/ovs-3.4.5.6.pem";
verify_identifier on;
proposal {
encryption_algorithm aes;
hash_algorithm sha1;
authentication_method rsasig;
dh_group 2;
}
}
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
AT_CHECK([cat etc/racoon/certs/ovs-3.4.5.6.pem], [0], [dnl
-----BEGIN CERTIFICATE-----
(not a real peer certificate)
-----END CERTIFICATE-----
])
###
### Delete the SSL certificate interface.
###
AT_CHECK([ovs-vsctl del-port gre2])
OVS_WAIT_UNTIL([test `wc -l < actions` -ge 41])
AT_CHECK([sed '1,33d' actions], [0], [dnl
racoon: reload
setkey:
> spddelete 0.0.0.0/0 3.4.5.6 gre -P out;
> spddelete 3.4.5.6 0.0.0.0/0 gre -P in;
setkey:
> dump ;
setkey:
> dump ;
])
AT_CHECK([trim etc/racoon/psk.txt], [0], [])
AT_CHECK([trim etc/racoon/racoon.conf], [0], [dnl
path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
sainfo anonymous {
pfs_group 2;
lifetime time 1 hour;
encryption_algorithm aes;
authentication_algorithm hmac_sha1, hmac_md5;
compression_algorithm deflate;
}
])
AT_CHECK([test ! -f etc/racoon/certs/ovs-3.4.5.6.pem])
dnl Skip SSL errors reported by Open vSwitch
OVS_VSWITCHD_STOP(["/stream_ssl/d"])
AT_CLEANUP

View File

@@ -63,7 +63,6 @@ m4_include([tests/bridge.at])
m4_include([tests/netdev-type.at])
m4_include([tests/ovsdb.at])
m4_include([tests/ovs-vsctl.at])
m4_include([tests/ovs-monitor-ipsec.at])
m4_include([tests/ovs-xapi-sync.at])
m4_include([tests/interface-reconfigure.at])
m4_include([tests/stp.at])

View File

@@ -158,7 +158,7 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 5'], [0], [dnl
port 5: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=?
])
AT_CHECK([ovs-appctl dpif/dump-flows int-br | grep 'in_port(6081)'], [0], [dnl
tunnel(tun_id=0x7b,ipv6_src=2001:cafe::92,ipv6_dst=2001:cafe::88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),skb_mark(0),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller))
tunnel(tun_id=0x7b,ipv6_src=2001:cafe::92,ipv6_dst=2001:cafe::88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller))
])
OVS_VSWITCHD_STOP

View File

@@ -163,7 +163,7 @@ AT_CHECK([ovs-ofctl dump-ports int-br | grep 'port 5'], [0], [dnl
port 5: rx pkts=1, bytes=98, drop=?, errs=?, frame=?, over=?, crc=?
])
AT_CHECK([ovs-appctl dpif/dump-flows int-br | grep 'in_port(6081)'], [0], [dnl
tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),skb_mark(0),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller))
tunnel(tun_id=0x7b,src=1.1.2.92,dst=1.1.2.88,geneve({class=0xffff,type=0x80,len=4,0xa/0xf}{class=0xffff,type=0,len=4}),flags(-df-csum+key)),recirc_id(0),in_port(6081),eth_type(0x0800),ipv4(frag=no), packets:0, bytes:0, used:never, actions:userspace(pid=0,slow_path(controller))
])
OVS_VSWITCHD_STOP

View File

@@ -82,28 +82,28 @@ AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl
dnl Tunnel CE and encapsulated packet CE
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=3,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=3,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=3,nw_frag=no
Datapath actions: 2
])
dnl Tunnel CE and encapsulated packet ECT(1)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=1,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=1,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=1,nw_frag=no
Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet ECT(2)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=2,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=2,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=2,nw_frag=no
Datapath actions: set(ipv4(tos=0x3/0x3)),2
])
dnl Tunnel CE and encapsulated packet Non-ECT
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'tunnel(src=1.1.1.1,dst=2.2.2.2,tos=0x3,ttl=64,flags()),in_port(1),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=0,ttl=64,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=0,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=3,tun_flags=-df-csum-key,in_port=1,nw_ecn=0,nw_frag=no
Datapath actions: drop
])
OVS_VSWITCHD_STOP(["/dropping tunnel packet marked ECN CE but is not ECN capable/d"])
@@ -196,75 +196,6 @@ AT_CHECK([tail -1 stdout], [0],
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([tunnel - encrypted tunnel and not setting skb_mark])
AT_SKIP_IF([test $HAVE_PYTHON = no])
AT_SKIP_IF([test "$IS_WIN32" = "yes"])
AT_SKIP_IF([$non_ascii_cwd])
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \
options:remote_ip=1.1.1.1 options:local_ip=2.2.2.2 \
options:key=5 ofport_request=1\
-- add-port br0 p2 -- set Interface p2 type=dummy \
ofport_request=2 ofport_request=2])
AT_DATA([flows.txt], [dnl
actions=output:1
])
OVS_MONITOR_IPSEC_START
AT_CHECK([ovs-vsctl set interface p1 type=ipsec_gre options:psk=1234567890])
OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=4,ttl=128,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))),set(skb_mark(0x1/0x1)),1
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([tunnel - encrypted tunnel and setting skb_mark to 1])
AT_SKIP_IF([test $HAVE_PYTHON = no])
AT_SKIP_IF([test "$IS_WIN32" = "yes"])
AT_SKIP_IF([$non_ascii_cwd])
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \
options:remote_ip=1.1.1.1 options:local_ip=2.2.2.2 \
options:key=5 ofport_request=1\
-- add-port br0 p2 -- set Interface p2 type=dummy \
ofport_request=2 ofport_request=2])
AT_DATA([flows.txt], [dnl
actions=load:0x1->NXM_NX_PKT_MARK[[]],output:1
])
OVS_MONITOR_IPSEC_START
AT_CHECK([ovs-vsctl set interface p1 type=ipsec_gre options:psk=1234567890])
OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=4,ttl=128,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))),set(skb_mark(0x1)),1
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([tunnel - encrypted tunnel and setting skb_mark to 2])
AT_SKIP_IF([test $HAVE_PYTHON = no])
AT_SKIP_IF([test "$IS_WIN32" = "yes"])
AT_SKIP_IF([$non_ascii_cwd])
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \
options:remote_ip=1.1.1.1 options:local_ip=2.2.2.2 \
options:key=5 ofport_request=1\
-- add-port br0 p2 -- set Interface p2 type=dummy \
ofport_request=2 ofport_request=2])
AT_DATA([flows.txt], [dnl
actions=load:0x2->NXM_NX_PKT_MARK[[]],output:1
])
OVS_MONITOR_IPSEC_START
AT_CHECK([ovs-vsctl set interface p1 type=ipsec_gre options:psk=1234567890])
OVS_VSWITCHD_DISABLE_TUNNEL_PUSH_POP
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(2),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=6,tos=4,ttl=128,frag=no),tcp(src=8,dst=9)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(tunnel(tun_id=0x5,src=2.2.2.2,dst=1.1.1.1,ttl=64,flags(df|key))),set(skb_mark(0x3)),1
])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([tunnel - ToS and TTL inheritance])
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gre \
options:remote_ip=1.1.1.1 options:tos=inherit \
@@ -559,14 +490,14 @@ AT_CHECK([tail -1 stdout], [0],
dnl Option match
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
Datapath actions: 2
])
dnl Skip unknown option
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0xb}{class=0xffff,type=2,len=4,0xc}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0=0xb/0xf,in_port=1,nw_frag=no
Datapath actions: 2
])
@@ -600,7 +531,7 @@ AT_CHECK([ovs-ofctl add-tlv-map br0 "{class=0xffff,type=3,len=8}->tun_metadata3"
AT_CHECK([ovs-ofctl add-flow br0 tun_metadata3=0x1234567890abcdef,actions=2])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=3,len=8,0x1234567890abcdef}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata3=0x1234567890abcdef,in_port=1,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata3=0x1234567890abcdef,in_port=1,nw_frag=no
Datapath actions: 2
])
@@ -635,13 +566,13 @@ NXST_FLOW reply:
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=0,len=4,0x12345678}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0,tun_metadata1=NP,tun_metadata2=NP,in_port=1,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata0,tun_metadata1=NP,tun_metadata2=NP,in_port=1,nw_frag=no
Datapath actions: 2
])
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x0,src=1.1.1.1,dst=1.1.1.2,ttl=64,geneve({class=0xffff,type=1,len=0}),flags(df|key)),in_port(6081),skb_mark(0),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
AT_CHECK([tail -2 stdout], [0],
[Megaflow: pkt_mark=0,recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata1,tun_metadata2=NP,in_port=1,nw_ecn=0,nw_frag=no
[Megaflow: recirc_id=0,ip,tun_id=0,tun_src=1.1.1.1,tun_dst=1.1.1.2,tun_tos=0,tun_flags=+df-csum+key,tun_metadata1,tun_metadata2=NP,in_port=1,nw_ecn=0,nw_frag=no
Datapath actions: set(tunnel(tun_id=0x0,dst=1.1.1.1,ttl=64,geneve({class=0xffff,type=0x1,len=0}),flags(df|key))),6081
])

View File

@@ -630,7 +630,7 @@ exclude those logs from the archive.
ovs_logs = ([OPENVSWITCH_LOG_DIR + x for x in
['ovs-vswitchd.log', 'ovsdb-server.log',
'ovs-xapi-sync.log', 'ovs-monitor-ipsec.log', 'ovs-ctl.log']])
'ovs-xapi-sync.log', 'ovs-ctl.log']])
for log in ovs_logs:
prefix_output(CAP_OPENVSWITCH_LOGS, log,
last_mod_time=log_last_mod_time)

View File

@@ -254,8 +254,8 @@ The default pattern for console and file output is \fB%D{%Y-%m-%dT
%H:%M:%SZ}|%05N|%c|%p|%m\fR; for syslog output, \fB%05N|%c|%p|%m\fR.
.
.IP
Daemons written in Python (e.g. \fBovs\-xapi\-sync\fR,
\fBovs\-monitor\-ipsec) do not allow control over the log pattern.
Daemons written in Python (e.g. \fBovs\-xapi\-sync\fR) do not allow
control over the log pattern.
.
.IP "\fBvlog/set\fR FACILITY:\fIfacility\fR"
Sets the RFC5424 facility of the log message. \fIfacility\fR can be one of

View File

@@ -2004,15 +2004,6 @@
tunnel.
</dd>
<dt><code>ipsec_gre</code></dt>
<dd>
An Ethernet over RFC 2890 Generic Routing Encapsulation over IPv4/IPv6
IPsec tunnel.
IPsec tunnel ports are deprecated. The support will be completely
removed in next version.
</dd>
<dt><code>vxlan</code></dt>
<dd>
<p>
@@ -2075,8 +2066,8 @@
<group title="Tunnel Options">
<p>
These options apply to interfaces with <ref column="type"/> of
<code>geneve</code>, <code>gre</code>, <code>ipsec_gre</code>,
<code>vxlan</code>, <code>lisp</code> and <code>stt</code>.
<code>geneve</code>, <code>gre</code>, <code>vxlan</code>,
<code>lisp</code> and <code>stt</code>.
</p>
<p>
@@ -2253,9 +2244,9 @@
</group>
<group title="Tunnel Options: gre, ipsec_gre, geneve, and vxlan">
<group title="Tunnel Options: gre, geneve, and vxlan">
<p>
<code>gre</code>, <code>ipsec_gre</code>, <code>geneve</code>, and
<code>gre</code>, <code>geneve</code>, and
<code>vxlan</code> interfaces support these options.
</p>
@@ -2277,43 +2268,6 @@
is compatible with.
</p>
<p>
This option is supported for <code>ipsec_gre</code>, but not useful
because GRE checksums are weaker than, and redundant with, IPsec
payload authentication.
</p>
</column>
</group>
<group title="Tunnel Options: ipsec_gre only">
<p>
Only <code>ipsec_gre</code> interfaces support these options.
</p>
<column name="options" key="peer_cert">
Required for certificate authentication. A string containing the
peer's certificate in PEM format. Additionally the host's
certificate must be specified with the <code>certificate</code>
option.
</column>
<column name="options" key="certificate">
Required for certificate authentication. The name of a PEM file
containing a certificate that will be presented to the peer during
authentication.
</column>
<column name="options" key="private_key">
Optional for certificate authentication. The name of a PEM file
containing the private key associated with <code>certificate</code>.
If <code>certificate</code> contains the private key, this option may
be omitted.
</column>
<column name="options" key="psk">
Required for pre-shared key authentication. Specifies a pre-shared
key for authentication that must be identical on both sides of the
tunnel.
</column>
</group>
</group>
@@ -4774,8 +4728,7 @@
<p>type: unsigned 8-bit integer.</p>
<p>data type semantics: identifier.</p>
<p>description: Identifier of the layer 2 network overlay network
encapsulation type: 0x01 VxLAN, 0x02 GRE, 0x03 LISP, 0x05 IPsec+GRE,
0x07 GENEVE.</p>
encapsulation type: 0x01 VxLAN, 0x02 GRE, 0x03 LISP, 0x07 GENEVE.</p>
</dd>
<dt>tunnelKey:</dt>
<dd>