From bfe8e67ad595348f228938663956c3b8325997c5 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 8 Feb 2010 15:37:49 -0800 Subject: [PATCH] ovsdb: Fix support for systems where libpcre is not installed. This is one of the loose ends that I intended to fix up and test before pushing off my commits to add use of PCRE, but obviously I forgot. --- INSTALL.Linux | 7 +++++++ lib/automake.mk | 1 - lib/ovsdb-types.c | 25 ++++++++++++++++++++++++- lib/ovsdb-types.h | 13 ++++++++++++- lib/pcre.h | 26 -------------------------- m4/openvswitch.m4 | 18 ++++++++++++------ tests/atlocal.in | 1 + tests/ovs-vsctl.at | 9 +++++++-- tests/ovsdb-data.at | 22 +++++++++++++++++----- tests/ovsdb-types.at | 21 ++++++++++++++++++--- 10 files changed, 98 insertions(+), 45 deletions(-) delete mode 100644 lib/pcre.h diff --git a/INSTALL.Linux b/INSTALL.Linux index c0344f23..65291186 100644 --- a/INSTALL.Linux +++ b/INSTALL.Linux @@ -27,6 +27,10 @@ you will need the following software: connections from an Open vSwitch to an OpenFlow controller. To enable, configure with --enable-ssl=yes. + - libpcre, the Perl Compatible Regular Expression library, is + optional but recommended. Without it, OVSDB will not be able to + validate regular-expression based contraints. + To compile the kernel module, you must also install the following. If you cannot build or install the kernel module, you may use the userspace-only implementation, at a cost in performance. The @@ -80,6 +84,9 @@ following software: - libssl compatible with the libssl used for build, if OpenSSL was used for the build. + - libpcre compatible with the libpcre used for build, if PCRE was + used for the build. + - The Linux kernel version configured as part of the build. - For optional support of ingress policing, the "tc" program from diff --git a/lib/automake.mk b/lib/automake.mk index e5a06487..51d3c11b 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -88,7 +88,6 @@ lib_libopenvswitch_a_SOURCES = \ lib/packets.h \ lib/pcap.c \ lib/pcap.h \ - lib/pcre.h \ lib/poll-loop.c \ lib/poll-loop.h \ lib/port-array.c \ diff --git a/lib/ovsdb-types.c b/lib/ovsdb-types.c index 1b5c7ed1..2cefd4d7 100644 --- a/lib/ovsdb-types.c +++ b/lib/ovsdb-types.c @@ -134,7 +134,9 @@ ovsdb_base_type_init(struct ovsdb_base_type *base, enum ovsdb_atomic_type type) break; case OVSDB_TYPE_STRING: +#ifdef HAVE_PCRE base->u.string.re = NULL; +#endif base->u.string.reMatch = NULL; base->u.string.reComment = NULL; base->u.string.minLen = 0; @@ -168,11 +170,21 @@ ovsdb_base_type_clone(struct ovsdb_base_type *dst, break; case OVSDB_TYPE_STRING: +#if HAVE_PCRE if (dst->u.string.re) { pcre_refcount(dst->u.string.re, 1); } +#else + if (dst->u.string.reMatch) { + dst->u.string.reMatch = xstrdup(dst->u.string.reMatch); + } + if (dst->u.string.reComment) { + dst->u.string.reComment = xstrdup(dst->u.string.reComment); + } +#endif break; + case OVSDB_TYPE_UUID: if (dst->u.uuid.refTableName) { dst->u.uuid.refTableName = xstrdup(dst->u.uuid.refTableName); @@ -197,11 +209,16 @@ ovsdb_base_type_destroy(struct ovsdb_base_type *base) break; case OVSDB_TYPE_STRING: +#ifdef HAVE_PCRE if (base->u.string.re && !pcre_refcount(base->u.string.re, -1)) { pcre_free(base->u.string.re); free(base->u.string.reMatch); free(base->u.string.reComment); } +#else + free(base->u.string.reMatch); + free(base->u.string.reComment); +#endif break; case OVSDB_TYPE_UUID: @@ -291,6 +308,7 @@ struct ovsdb_error * ovsdb_base_type_set_regex(struct ovsdb_base_type *base, const char *reMatch, const char *reComment) { +#ifdef HAVE_PCRE const char *errorString; const char *pattern; int errorOffset; @@ -300,6 +318,10 @@ ovsdb_base_type_set_regex(struct ovsdb_base_type *base, if (pattern[0] == '\0' || strchr(pattern, '\0')[-1] != '$') { pattern = xasprintf("%s$", pattern); } + +#ifndef PCRE_JAVASCRIPT_COMPAT /* Added in PCRE 7.7. */ +#define PCRE_JAVASCRIPT_COMPAT 0 +#endif base->u.string.re = pcre_compile(pattern, (PCRE_ANCHORED | PCRE_UTF8 | PCRE_JAVASCRIPT_COMPAT), &errorString, &errorOffset, NULL); @@ -311,9 +333,10 @@ ovsdb_base_type_set_regex(struct ovsdb_base_type *base, "\"%s\" is not a valid regular " "expression: %s", reMatch, errorString); } + pcre_refcount(base->u.string.re, 1); +#endif /* Save regular expression. */ - pcre_refcount(base->u.string.re, 1); base->u.string.reMatch = xstrdup(reMatch); base->u.string.reComment = reComment ? xstrdup(reComment) : NULL; return NULL; diff --git a/lib/ovsdb-types.h b/lib/ovsdb-types.h index b11f8277..0eca931f 100644 --- a/lib/ovsdb-types.h +++ b/lib/ovsdb-types.h @@ -17,12 +17,15 @@ #define OVSDB_TYPES_H 1 #include -#include #include #include #include "compiler.h" #include "uuid.h" +#ifdef HAVE_PCRE +#include +#endif + struct json; /* An atomic type: one that OVSDB regards as a single unit of data. */ @@ -61,7 +64,9 @@ struct ovsdb_base_type { /* No constraints for Boolean types. */ struct ovsdb_string_constraints { +#ifdef HAVE_PCRE pcre *re; /* Compiled regular expression. */ +#endif char *reMatch; /* reMatch or NULL. */ char *reComment; /* reComment or NULL. */ unsigned int minLen; /* minLength or 0. */ @@ -81,9 +86,15 @@ struct ovsdb_base_type { #define OVSDB_BASE_REAL_INIT { .type = OVSDB_TYPE_REAL, \ .u.real = { -DBL_MAX, DBL_MAX } } #define OVSDB_BASE_BOOLEAN_INIT { .type = OVSDB_TYPE_BOOLEAN } +#ifdef HAVE_PCRE #define OVSDB_BASE_STRING_INIT { .type = OVSDB_TYPE_STRING, \ .u.string = { NULL, NULL, NULL, \ 0, UINT_MAX } } +#else +#define OVSDB_BASE_STRING_INIT { .type = OVSDB_TYPE_STRING, \ + .u.string = { NULL, NULL, \ + 0, UINT_MAX } } +#endif #define OVSDB_BASE_UUID_INIT { .type = OVSDB_TYPE_UUID, \ .u.uuid = { NULL, NULL } } diff --git a/lib/pcre.h b/lib/pcre.h deleted file mode 100644 index 5ade8331..00000000 --- a/lib/pcre.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010 Nicira Networks. - * - * 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. - */ - -#ifndef PCRE_H -#define PCRE_H 1 - -#ifdef HAVE_PCRE -#include_next -#else -typedef void pcre; -#endif - -#endif /* pcre.h */ diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 index affeac35..861e4ebd 100644 --- a/m4/openvswitch.m4 +++ b/m4/openvswitch.m4 @@ -224,16 +224,22 @@ dnl which is libpcre 7.2 or later. AC_DEFUN([OVS_CHECK_PCRE], [dnl Make sure that pkg-config is installed. m4_pattern_forbid([PKG_CHECK_MODULES]) - HAVE_PCRE=no - HAVE_PCRE_PARTIAL=no - PKG_CHECK_MODULES([PCRE], [libpcre >= 6.6], - [HAVE_PCRE=yes - PKG_CHECK_EXISTS([libpcre >= 7.2], [HAVE_PCRE_PARTIAL=yes])]) + PKG_CHECK_MODULES([PCRE], + [libpcre >= 6.6], + [HAVE_PCRE=yes + PKG_CHECK_EXISTS([libpcre >= 7.2], + [HAVE_PCRE_PARTIAL=yes], + [HAVE_PCRE_PARTIAL=no])], + [HAVE_PCRE=no + HAVE_PCRE_PARTIAL=no]) AM_CONDITIONAL([HAVE_PCRE], [test "$HAVE_PCRE" = yes]) AM_CONDITIONAL([HAVE_PCRE_PARTIAL], [test "$HAVE_PCRE_PARTIAL" = yes]) if test "$HAVE_PCRE" = yes; then AC_DEFINE([HAVE_PCRE], [1], [Define to 1 if libpcre is installed.]) - fi]) + fi + AC_SUBST([HAVE_PCRE]) + AC_SUBST([HAVE_PCRE_PARTIAL]) +]) dnl Checks for Python 2.x, x >= 4. AC_DEFUN([OVS_CHECK_PYTHON], diff --git a/tests/atlocal.in b/tests/atlocal.in index 8ac4f676..1628ea55 100644 --- a/tests/atlocal.in +++ b/tests/atlocal.in @@ -1,5 +1,6 @@ # -*- shell-script -*- HAVE_OPENSSL='@HAVE_OPENSSL@' +HAVE_PCRE='@HAVE_PCRE@' HAVE_PYTHON='@HAVE_PYTHON@' PERL='@PERL@' PYTHON='@PYTHON@' diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at index 103b17ae..b140f025 100644 --- a/tests/ovs-vsctl.at +++ b/tests/ovs-vsctl.at @@ -562,9 +562,14 @@ AT_CHECK([RUN_OVS_VSCTL([set b br0 flood_vlans=-1])], AT_CHECK([RUN_OVS_VSCTL([set b br0 flood_vlans=4096])], [1], [], [ovs-vsctl: constraint violation: 4096 is not in the valid range 0 to 4095 (inclusive) ], [OVS_VSCTL_CLEANUP]) -AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], - [1], [], [ovs-vsctl: constraint violation: "xyz" is not a either "in-band" or "out-of-band" +if test "$HAVE_PCRE" = yes; then + AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], + [1], [], [ovs-vsctl: constraint violation: "xyz" is not a either "in-band" or "out-of-band" ], [OVS_VSCTL_CLEANUP]) +else + AT_CHECK([RUN_OVS_VSCTL([set c br1 'connection-mode=xyz'])], + [0], [], [], [OVS_VSCTL_CLEANUP]) +fi AT_CHECK([RUN_OVS_VSCTL([set c br1 connection-mode:x=y])], [1], [], [ovs-vsctl: cannot specify key to set for non-map column connection_mode ], [OVS_VSCTL_CLEANUP]) diff --git a/tests/ovsdb-data.at b/tests/ovsdb-data.at index 03ec3b33..708ed905 100644 --- a/tests/ovsdb-data.at +++ b/tests/ovsdb-data.at @@ -290,8 +290,17 @@ constraint violation: -11 is not in the valid range -10 to 10 (inclusive) constraint violation: 11 is not in the valid range -10 to 10 (inclusive) constraint violation: 123576 is not in the valid range -10 to 10 (inclusive)]) -OVSDB_CHECK_POSITIVE([strings matching /(a(b)?)c?/], - [[parse-atoms '{"type": "string", "reMatch": "(a(b)?)?c?"}' \ +AT_SETUP([strings matching /(a(b)?)c?/]) +AT_KEYWORDS([ovsdb positive]) +if test "$HAVE_PCRE" = yes; then + b_out='constraint violation: "b" does not match regular expression /(a(b)?)?c?/' + bc_out='constraint violation: "bc" does not match regular expression /(a(b)?)?c?/' +else + b_out='"b"' + bc_out='"bc"' +fi +AT_CHECK_UNQUOTED( + [[test-ovsdb parse-atoms '{"type": "string", "reMatch": "(a(b)?)?c?"}' \ '[""]' \ '["a"]' \ '["ab"]' \ @@ -300,14 +309,17 @@ OVSDB_CHECK_POSITIVE([strings matching /(a(b)?)c?/], '["b"]' \ '["bc"]' \ '["c"]']], + [0], [["" "a" "ab" "abc" "ac" -constraint violation: "b" does not match regular expression /(a(b)?)?c?/ -constraint violation: "bc" does not match regular expression /(a(b)?)?c?/ -"c"]]) +$b_out +$bc_out +"c" +]]) +AT_CLEANUP OVSDB_CHECK_POSITIVE([strings at least 2 characters long], [[parse-atoms '{"type": "string", "minLength": 2}' \ diff --git a/tests/ovsdb-types.at b/tests/ovsdb-types.at index 4647e69d..d0527766 100644 --- a/tests/ovsdb-types.at +++ b/tests/ovsdb-types.at @@ -50,9 +50,24 @@ OVSDB_CHECK_POSITIVE([string reMatch], OVSDB_CHECK_POSITIVE([string reMatch + reComment], [[parse-base-type '{"type": "string", "reMatch": "\\d{3}-\\d{3}-\\d{4}", "reComment": "US-style telephone number"}']], [{"reComment":"US-style telephone number","reMatch":"\\d{3}-\\d{3}-\\d{4}","type":"string"}]) -OVSDB_CHECK_NEGATIVE([reMatch must be a valid JavaScript regexp], - [[parse-base-type '{"type": "string", "reMatch": "ab@:>@cd"}']], - [[test-ovsdb: invalid regular expression: "ab@:>@cd" is not a valid regular expression: @:>@ is an invalid data character in JavaScript compatibility mode]]) + +AT_SETUP([reMatch must be a valid regexp]) +AT_KEYWORDS([ovsdb negative]) +if test "$HAVE_PCRE" = yes; then + AT_CHECK( + [[test-ovsdb parse-base-type \ + '{"type": "string", "reMatch": "x{2,1}"}']], + [1], [], + [[test-ovsdb: invalid regular expression: "x{2,1}" is not a valid regular expression: numbers out of order in {} quantifier +]]) +else + AT_CHECK( + [[test-ovsdb parse-base-type \ + '{"type": "string", "reMatch": "x{2,1}"}']], + [0], [[{"reMatch":"x{2,1}","type":"string"} +]], []) +fi +AT_CLEANUP OVSDB_CHECK_POSITIVE([string minLength], [[parse-base-type '{"type": "string", "minLength": 1}']], -- 2.30.2