From 76e504a38a3c556884782323459cc6862a38747c Mon Sep 17 00:00:00 2001 From: Muthukrishnan T <muthukrishna...@tataelxsi.co.in> Date: Thu, 29 Sep 2016 12:21:29 +0530 Subject: [PATCH] ovs-monitor-ipsec: ipsec_vxlan support and IPsec tunnel mode options support.
Description : OpenvSwitch doesn’t have support for IPSec Tunnel interface ‘ipsec_vxlan’ for VxLAN traffic. It supports only IPSec Transport mode for IPSec tunnel interfaces (i.e.) GRE/VxLAN, doesn’t have options for IPSec Tunnel mode of operation , this patch addresses the same. Signed-off-by: Muthukrishnan T <muthukrishna...@tataelxsi.co.in> --- NEWS | 3 + debian/ovs-monitor-ipsec | 140 +++++++++---- lib/dpif-netlink.c | 2 +- lib/netdev-vport.c | 39 +++- ofproto/ofproto-dpif-ipfix.c | 5 + tests/ovs-monitor-ipsec.at | 483 +++++++++++++++++++++++++++++++++++++++++-- vswitchd/vswitch.xml | 6 + 7 files changed, 615 insertions(+), 63 deletions(-) diff --git a/NEWS b/NEWS index bb32c47..95c7e99 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,9 @@ 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.) + - The ovs-monitor-ipsec daemon provides support for encrypting VxLAN Traffic. + - New option 'mode=tunnel/transport' added for the interface + ipsec_gre and ipsec_vxlan. v2.6.0 - xx xxx xxxx --------------------- diff --git a/debian/ovs-monitor-ipsec b/debian/ovs-monitor-ipsec index 6bc26aa..a716201 100755 --- a/debian/ovs-monitor-ipsec +++ b/debian/ovs-monitor-ipsec @@ -14,7 +14,7 @@ # limitations under the License. -# A daemon to monitor attempts to create GRE-over-IPsec tunnels. +# A daemon to monitor attempts to create GRE-over-IPsec and VxLAN-over-IPsec tunnels. # Uses racoon and setkey to support the configuration. Assumes that # OVS has complete control over IPsec configuration for the box. @@ -30,6 +30,7 @@ import glob import os import subprocess import sys +import socket import ovs.dirs from ovs.db import error @@ -48,6 +49,11 @@ SETKEY = "/usr/sbin/setkey" IP = "/sbin/ip" exiting = False IPSEC_MARK = "1" +# UDP ports used for VXLAN. The source port is only fixed for +# VXLAN-over-IPsec traffic. + +VXLAN_SRC_PORT = "any" +VXLAN_DST_PORT = "4789" def unixctl_exit(conn, unused_argv, unused_aux): @@ -266,7 +272,7 @@ class IPsec(object): self.sad_flush() self.spd_flush() self.racoon = Racoon() - self.entries = [] + self.entries = {} def call_setkey(self, cmds): try: @@ -335,35 +341,71 @@ class IPsec(object): "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_add(self, local_ip, remote_ip, tunnel_mode): + tunnel_type = self.entries[remote_ip] + cmds = "" + if tunnel_type == "vxlan" and tunnel_mode == "tunnel": + cmds = ("spdadd %s[%s] %s udp -P out ipsec esp/tunnel/%s-%s/require;\n" + % (local_ip, VXLAN_SRC_PORT, remote_ip, local_ip, remote_ip)) + cmds += ("spdadd %s %s[%s] udp -P in ipsec esp/tunnel/%s-%s/require;\n" + % (remote_ip, local_ip, VXLAN_SRC_PORT, remote_ip, local_ip)) + elif tunnel_type == "vxlan" and tunnel_mode == "transport": + cmds = ("spdadd %s[%s] %s udp -P out ipsec esp/transport//require;\n" + % (local_ip, VXLAN_SRC_PORT, remote_ip)) + cmds += ("spdadd %s %s[%s] udp -P in ipsec esp/transport//require;\n" + % (remote_ip, local_ip, VXLAN_SRC_PORT)) + elif tunnel_type == "gre" and tunnel_mode == "tunnel": + cmds = ("spdadd %s %s gre -P out ipsec esp/tunnel/%s-%s/require;\n" + % (local_ip, remote_ip, local_ip, remote_ip)) + cmds += ("spdadd %s %s gre -P in ipsec esp/tunnel/%s-%s/require;\n" + % (remote_ip, local_ip, remote_ip, local_ip)) + elif tunnel_type == "gre" and tunnel_mode == "transport": + 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)) + else: + vlog.err("Unsupported IPsec Mode %s Received" % tunnel_mode) + if cmds: + vlog.info("IPsec Policy: %s" % cmds) + 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) + tunnel_type = self.entries[remote_ip] + cmds= "" + if tunnel_type == "vxlan": + cmds = ("spddelete %s %s udp -P out;\n" % (local_ip, remote_ip)) + cmds += ("spddelete %s %s udp -P in;\n" % (remote_ip, local_ip)) + else: + cmds = "spddelete %s %s gre -P out;\n" % (local_ip, remote_ip) + cmds += "spddelete %s %s gre -P in;\n" % (remote_ip, local_ip) + if cmds: + vlog.info(" Command:%s" % cmds) + self.call_setkey(cmds) def add_entry(self, local_ip, remote_ip, vals): + tunnel_type = vals["tunnel_type"] + tunnel_mode = vals["tunnel_mode"] + vlog.warn("Tunnel type in add_entry %s" % tunnel_type) + if tunnel_type not in ("gre", "vxlan"): + raise error.Error("unknown tunnel type: %s" % tunnel_type) + 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) + self.entries[remote_ip] = tunnel_type + self.spd_add(local_ip, remote_ip, tunnel_mode) 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) + + del self.entries[remote_ip] - self.entries.remove(remote_ip) def update_ipsec(ipsec, interfaces, new_interfaces): @@ -398,6 +440,10 @@ def get_ssl_cert(data): return None +def get_local_ip(): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect(("8.8.8.8", 80)) + return s.getsockname()[0] def main(): @@ -453,40 +499,50 @@ def main(): ssl_cert = get_ssl_cert(idl.tables) new_interfaces = {} + loc_ip = get_local_ip() 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 + tunnel_type = "gre" + elif rec.type == "ipsec_vxlan": + tunnel_type = "vxlan" + else: + continue + name = rec.name + options = rec.options + peer_cert_name = "ovs-%s.pem" % (options.get("remote_ip")) + vlog.info("local ip received from def:get_local_ip %s" % loc_ip) + entry = { + "remote_ip": options.get("remote_ip"), + "local_ip": options.get("local_ip", loc_ip), + "certificate": options.get("certificate"), + "private_key": options.get("private_key"), + "use_ssl_cert": options.get("use_ssl_cert"), + "peer_cert": options.get("peer_cert"), + "psk": options.get("psk"), + "tunnel_mode": options.get("mode","transport"), + "peer_cert_file": Racoon.cert_dir + "/" + peer_cert_name, + "tunnel_type": tunnel_type } + + vlog.info("IPsec mode received %s" % entry["tunnel_mode"]) + if entry["peer_cert"] and entry["psk"]: + vlog.warn("both 'peer_cert' and '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 + # 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] - entry["certificate"] = ssl_cert[0] - entry["private_key"] = ssl_cert[1] - new_interfaces[name] = entry + new_interfaces[name] = entry if interfaces != new_interfaces: update_ipsec(ipsec, interfaces, new_interfaces) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index a39faa2..67cf6e8 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -794,7 +794,7 @@ netdev_to_ovs_vport_type(const struct netdev *netdev) return OVS_VPORT_TYPE_GENEVE; } else if (strstr(type, "gre")) { return OVS_VPORT_TYPE_GRE; - } else if (!strcmp(type, "vxlan")) { + } else if (strstr(type, "vxlan")) { return OVS_VPORT_TYPE_VXLAN; } else if (!strcmp(type, "lisp")) { return OVS_VPORT_TYPE_LISP; diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 8d22cf5..f343cb4 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -108,7 +108,7 @@ netdev_vport_needs_dst_port(const struct netdev *dev) const char *type = netdev_get_type(dev); return (class->get_config == get_tunnel_config && - (!strcmp("geneve", type) || !strcmp("vxlan", type) || + (!strcmp("geneve", type) || strstr("vxlan", type) || !strcmp("lisp", type) || !strcmp("stt", type)) ); } @@ -195,7 +195,7 @@ netdev_vport_construct(struct netdev *netdev_) /* Add a default destination port for tunnel ports if none specified. */ if (!strcmp(type, "geneve")) { dev->tnl_cfg.dst_port = htons(GENEVE_DST_PORT); - } else if (!strcmp(type, "vxlan")) { + } else if (strstr(type, "vxlan")) { dev->tnl_cfg.dst_port = htons(VXLAN_DST_PORT); } else if (!strcmp(type, "lisp")) { dev->tnl_cfg.dst_port = htons(LISP_DST_PORT); @@ -335,7 +335,6 @@ netdev_vport_wait(const struct netdev_class *netdev_class OVS_UNUSED) poll_immediate_wake(); } } - /* Code specific to tunnel types. */ static ovs_be64 @@ -402,7 +401,7 @@ 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 ipsec_mech_set, needs_dst_port, has_csum , ipsec_mode_set; uint16_t dst_proto = 0, src_proto = 0; struct netdev_tunnel_config tnl_cfg; struct smap_node *node; @@ -410,6 +409,7 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) has_csum = strstr(type, "gre") || strstr(type, "geneve") || strstr(type, "stt") || strstr(type, "vxlan"); ipsec_mech_set = false; + ipsec_mode_set = false; memset(&tnl_cfg, 0, sizeof tnl_cfg); /* Add a default destination port for tunnel ports if none specified. */ @@ -417,7 +417,7 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) tnl_cfg.dst_port = htons(GENEVE_DST_PORT); } - if (!strcmp(type, "vxlan")) { + if (strstr(type, "vxlan")) { tnl_cfg.dst_port = htons(VXLAN_DST_PORT); } @@ -429,8 +429,12 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) tnl_cfg.dst_port = htons(STT_DST_PORT); } + if ((strstr(type, "ipsec"))) { + tnl_cfg.ipsec = true; + ipsec_mode_set = true; + } + 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) { @@ -507,6 +511,11 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) } } else if (!strcmp(node->key, "psk") && tnl_cfg.ipsec) { ipsec_mech_set = true; + } else if (!strcmp(node->key, "mode") && tnl_cfg.ipsec) { + if ((strcmp(node->value, "tunnel")) && (strcmp(node->value, "transport"))) { + ipsec_mode_set = false; + VLOG_WARN("IPsec mode received: '%s'",node->value); + } } else if (tnl_cfg.ipsec && (!strcmp(node->key, "certificate") || !strcmp(node->key, "private_key") @@ -535,7 +544,13 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) free(str); } else { - VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key); + if ((!strcmp(node->key, "psk")) || (!strcmp(node->key, "mode"))) { + VLOG_ERR("%s: IPsec argument '%s' not supported for interface type '%s'", + name,node->key,type); + return EINVAL; + } else { + VLOG_WARN("%s: unknown %s argument '%s'", name, type, node->key); + } } } @@ -570,6 +585,11 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args) name); return EINVAL; } + if (!ipsec_mode_set) { + VLOG_ERR("%s: IPsec mode requires an 'tunnel' or 'transport' argument", + name); + return EINVAL; + } } if (!ipv6_addr_is_set(&tnl_cfg.ipv6_dst) && !tnl_cfg.ip_dst_flow) { @@ -670,7 +690,7 @@ get_tunnel_config(const struct netdev *dev, struct smap *args) const char *type = netdev_get_type(dev); if ((!strcmp("geneve", type) && dst_port != GENEVE_DST_PORT) || - (!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) || + (strstr("vxlan", type) && dst_port != VXLAN_DST_PORT) || (!strcmp("lisp", type) && dst_port != LISP_DST_PORT) || (!strcmp("stt", type) && dst_port != STT_DST_PORT)) { smap_add_format(args, "dst_port", "%d", dst_port); @@ -900,6 +920,9 @@ netdev_vport_tunnel_register(void) TUNNEL_CLASS("vxlan", "vxlan_sys", netdev_vxlan_build_header, netdev_tnl_push_udp_header, netdev_vxlan_pop_header), + TUNNEL_CLASS("ipsec_vxlan", "vxlan_sys", netdev_vxlan_build_header, + netdev_tnl_push_udp_header, + netdev_vxlan_pop_header), TUNNEL_CLASS("lisp", "lisp_sys", NULL, NULL, NULL), TUNNEL_CLASS("stt", "stt_sys", NULL, NULL, NULL), }; diff --git a/ofproto/ofproto-dpif-ipfix.c b/ofproto/ofproto-dpif-ipfix.c index abea492..aef3c1a 100644 --- a/ofproto/ofproto-dpif-ipfix.c +++ b/ofproto/ofproto-dpif-ipfix.c @@ -80,6 +80,7 @@ enum dpif_ipfix_tunnel_type { DPIF_IPFIX_TUNNEL_STT = 0x04, DPIF_IPFIX_TUNNEL_IPSEC_GRE = 0x05, DPIF_IPFIX_TUNNEL_GENEVE = 0x07, + DPIF_IPFIX_TUNNEL_IPSEC_VXLAN = 0x08, NUM_DPIF_IPFIX_TUNNEL }; @@ -323,6 +324,7 @@ static uint8_t tunnel_protocol[NUM_DPIF_IPFIX_TUNNEL] = { IPPROTO_GRE, /* DPIF_IPFIX_TUNNEL_IPSEC_GRE */ 0 , /* reserved */ IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_GENEVE*/ + IPPROTO_UDP, /* DPIF_IPFIX_TUNNEL_IPSEC_VXLAN*/ }; OVS_PACKED( @@ -664,6 +666,9 @@ dpif_ipfix_add_tunnel_port(struct dpif_ipfix *di, struct ofport *ofport, } else if (strcmp(type, "vxlan") == 0) { dip->tunnel_type = DPIF_IPFIX_TUNNEL_VXLAN; dip->tunnel_key_length = 3; + } else if (strcmp(type, "ipsec_vxlan") == 0) { + dip->tunnel_type = DPIF_IPFIX_TUNNEL_IPSEC_VXLAN; + dip->tunnel_key_length = 3; } else if (strcmp(type, "lisp") == 0) { dip->tunnel_type = DPIF_IPFIX_TUNNEL_LISP; dip->tunnel_key_length = 3; diff --git a/tests/ovs-monitor-ipsec.at b/tests/ovs-monitor-ipsec.at index cae2878..e2427f2 100644 --- a/tests/ovs-monitor-ipsec.at +++ b/tests/ovs-monitor-ipsec.at @@ -18,6 +18,7 @@ OVS_MONITOR_IPSEC_START AT_CHECK([ovs-vsctl \ -- add-port br0 gre0 \ -- set interface gre0 type=ipsec_gre \ + options:local_ip=0.0.0.0 \ 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]) @@ -29,8 +30,8 @@ setkey: 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; +> spdadd 0.0.0.0 1.2.3.4 gre -P out ipsec esp/transport//require; +> spdadd 1.2.3.4 0.0.0.0 gre -P in ipsec esp/transport//require; ]) AT_CHECK([trim etc/racoon/psk.txt], [0], [1.2.3.4 swordfish ]) @@ -64,8 +65,8 @@ 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; +> spddelete 0.0.0.0 1.2.3.4 gre -P out; +> spddelete 1.2.3.4 0.0.0.0 gre -P in; setkey: > dump ; setkey: @@ -100,6 +101,7 @@ AT_DATA([key.pem], [dnl AT_CHECK([ovs-vsctl \ -- add-port br0 gre1 \ -- set Interface gre1 type=ipsec_gre \ + options:local_ip=0.0.0.0 \ options:remote_ip=2.3.4.5 \ options:peer_cert='"-----BEGIN CERTIFICATE----- (not a real peer certificate) @@ -111,8 +113,8 @@ 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; +> spdadd 0.0.0.0 2.3.4.5 gre -P out ipsec esp/transport//require; +> spdadd 2.3.4.5 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 @@ -156,8 +158,8 @@ 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; +> spddelete 0.0.0.0 2.3.4.5 gre -P out; +> spddelete 2.3.4.5 0.0.0.0 gre -P in; setkey: > dump ; setkey: @@ -190,6 +192,7 @@ AT_DATA([ssl-cacert.pem], [dnl 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:local_ip=0.0.0.0 \ options:remote_ip=3.4.5.6 \ options:peer_cert='"-----BEGIN CERTIFICATE----- (not a real peer certificate) @@ -200,8 +203,8 @@ 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; +> spdadd 0.0.0.0 3.4.5.6 gre -P out ipsec esp/transport//require; +> spdadd 3.4.5.6 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 @@ -245,8 +248,464 @@ 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; +> spddelete 0.0.0.0 3.4.5.6 gre -P out; +> spddelete 3.4.5.6 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]) + +### +### Add an ipsec_gre psk interface with mode as transport and check what ovs-monitor-ipsec does +### +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:local_ip=0.0.0.0 \ + options:remote_ip=1.2.3.4 \ + options:mode=transport \ + options:psk=swordfish]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 45]) +AT_CHECK([sed '1,41d' actions], [0], [dnl +racoon: reload +setkey: +> spdadd 0.0.0.0 1.2.3.4 gre -P out ipsec esp/transport//require; +> spdadd 1.2.3.4 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 gre2]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 53]) +AT_CHECK([sed '1,45d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 1.2.3.4 gre -P out; +> spddelete 1.2.3.4 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 an ipsec_gre psk interface with mode as tunnel and check what ovs-monitor-ipsec does +### +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:local_ip=0.0.0.0 \ + options:remote_ip=1.2.3.4 \ + options:mode=tunnel \ + options:psk=swordfish]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 57]) +AT_CHECK([sed '1,53d' actions], [0], [dnl +racoon: reload +setkey: +> spdadd 0.0.0.0 1.2.3.4 gre -P out ipsec esp/tunnel/0.0.0.0-1.2.3.4/require; +> spdadd 1.2.3.4 0.0.0.0 gre -P in ipsec esp/tunnel/1.2.3.4-0.0.0.0/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 gre2]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 65]) +AT_CHECK([sed '1,57d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 1.2.3.4 gre -P out; +> spddelete 1.2.3.4 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 an ipsec_vxlan psk interface with mode as transport and check what ovs-monitor-ipsec does +### +AT_CHECK([ovs-vsctl set-ssl /ssl-key.pem /ssl-cert.pem /ssl-cacert.pem \ + -- add-port br0 vxlan1 \ + -- set Interface vxlan1 type=ipsec_vxlan \ + options:local_ip=0.0.0.0 \ + options:remote_ip=1.2.3.4 \ + options:mode=transport \ + options:psk=swordfish]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 69]) +AT_CHECK([sed '1,65d' actions], [0], +[[racoon: reload +setkey: +> spdadd 0.0.0.0[any] 1.2.3.4 udp -P out ipsec esp/transport//require; +> spdadd 1.2.3.4 0.0.0.0[any] udp -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_vxlan interface and check what ovs-monitor-ipsec does +### +AT_CHECK([ovs-vsctl del-port vxlan1]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 77]) +AT_CHECK([sed '1,69d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 1.2.3.4 udp -P out; +> spddelete 1.2.3.4 0.0.0.0 udp -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 an ipsec_vxlan psk interface with mode as tunnel and check what ovs-monitor-ipsec does +### +AT_CHECK([ovs-vsctl set-ssl /ssl-key.pem /ssl-cert.pem /ssl-cacert.pem \ + -- add-port br0 vxlan1 \ + -- set Interface vxlan1 type=ipsec_vxlan \ + options:local_ip=0.0.0.0 \ + options:remote_ip=1.2.3.4 \ + options:mode=tunnel \ + options:psk=swordfish]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 81]) +AT_CHECK([sed '1,77d' actions], [0], +[[racoon: reload +setkey: +> spdadd 0.0.0.0[any] 1.2.3.4 udp -P out ipsec esp/tunnel/0.0.0.0-1.2.3.4/require; +> spdadd 1.2.3.4 0.0.0.0[any] udp -P in ipsec esp/tunnel/1.2.3.4-0.0.0.0/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_vxlan interface and check what ovs-monitor-ipsec does +### +AT_CHECK([ovs-vsctl del-port vxlan1]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 89]) +AT_CHECK([sed '1,81d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 1.2.3.4 udp -P out; +> spddelete 1.2.3.4 0.0.0.0 udp -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_vxlan 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 vxlan1 \ + -- set Interface vxlan1 type=ipsec_vxlan \ + options:local_ip=0.0.0.0 \ + 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 93]) +AT_CHECK([sed '1,89d' actions], [0], +[[racoon: reload +setkey: +> spdadd 0.0.0.0[any] 2.3.4.5 udp -P out ipsec esp/transport//require; +> spdadd 2.3.4.5 0.0.0.0[any] udp -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_vxlan certificate interface. +### +AT_CHECK([ovs-vsctl del-port vxlan1]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 101]) +AT_CHECK([sed '1,93d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 2.3.4.5 udp -P out; +> spddelete 2.3.4.5 0.0.0.0 udp -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 vxlan1 \ + -- set Interface vxlan1 type=ipsec_vxlan \ + options:local_ip=0.0.0.0 \ + 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 105]) +AT_CHECK([sed '1,101d' actions], [0], +[[racoon: reload +setkey: +> spdadd 0.0.0.0[any] 3.4.5.6 udp -P out ipsec esp/transport//require; +> spdadd 3.4.5.6 0.0.0.0[any] udp -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 vxlan1]) +OVS_WAIT_UNTIL([test `wc -l < actions` -ge 113]) +AT_CHECK([sed '1,105d' actions], [0], [dnl +racoon: reload +setkey: +> spddelete 0.0.0.0 3.4.5.6 udp -P out; +> spddelete 3.4.5.6 0.0.0.0 udp -P in; setkey: > dump ; setkey: diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml index e73023d..ee80ada 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -2010,6 +2010,12 @@ IPsec tunnel. </dd> + <dt><code>ipsec_vxlan</code></dt> + <dd> + An Ethernet over RFC 7348 Virtual eXtensible Local Area Network + (VXLAN) over IPv4 IPsec tunnel. + </dd> + <dt><code>vxlan</code></dt> <dd> <p> -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev