Merge branch 'mainstream'
authorGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Thu, 24 Jan 2013 10:05:16 +0000 (11:05 +0100)
committerGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Thu, 24 Jan 2013 10:05:16 +0000 (11:05 +0100)
129 files changed:
AUTHORS
FAQ
Makefile.am
NEWS
configure.ac
datapath/datapath.c
datapath/flow.c
datapath/flow.h
datapath/tunnel.h
datapath/vport-netdev.c
debian/changelog
debian/openvswitch-datapath-module-_KVERS_.postinst.modules.in
include/linux/openvswitch.h
lib/aes128.c
lib/automake.mk
lib/bond.c
lib/byteq.c
lib/cfm.c
lib/classifier.c
lib/compiler.h
lib/daemon.c
lib/dpif-linux.c
lib/dpif-netdev.c
lib/dpif-provider.h
lib/dpif.c
lib/dynamic-string.c
lib/fatal-signal.c
lib/flow.c
lib/hash.c
lib/hash.h
lib/hmap.c
lib/hmapx.c
lib/jhash.c [new file with mode: 0644]
lib/jhash.h [new file with mode: 0644]
lib/json.c
lib/jsonrpc.c
lib/lacp.c
lib/learning-switch.c
lib/list.c
lib/mac-learning.c
lib/match.c
lib/meta-flow.c
lib/netdev-bsd.c
lib/netdev-dummy.c
lib/netdev-linux.c
lib/netdev-provider.h
lib/netdev-vport.c
lib/netdev.c
lib/netlink-notifier.c
lib/netlink-socket.c
lib/netlink.c
lib/nx-match.c
lib/odp-util.c
lib/odp-util.h
lib/ofp-actions.c
lib/ofp-actions.h
lib/ofp-errors.c
lib/ofp-msgs.c
lib/ofp-util.c
lib/ofp-util.h
lib/ofpbuf.c
lib/ovsdb-data.c
lib/ovsdb-idl.c
lib/packets.c
lib/pcap.c
lib/poll-loop.c
lib/process.c
lib/random.c
lib/rconn.c
lib/reconnect.c
lib/route-table.c
lib/sat-math.h
lib/shash.c
lib/signals.c
lib/simap.c
lib/smap.c
lib/socket-util.c
lib/sset.c
lib/stp.c
lib/stream-fd.c
lib/stream-provider.h
lib/stream-ssl.c
lib/stream-unix.c
lib/stream.c
lib/svec.c
lib/table.c
lib/tag.h
lib/timeval.c
lib/unixctl.c
lib/util.c
lib/util.h
lib/vconn-provider.h
lib/vconn-stream.c
lib/vconn.c
lib/vlog.c
lib/worker.c
ofproto/connmgr.c
ofproto/ofproto-dpif-governor.c
ofproto/ofproto-dpif.c
ofproto/ofproto.c
ovsdb/execution.c
ovsdb/file.c
ovsdb/jsonrpc-server.c
ovsdb/log.c
ovsdb/ovsdb-client.c
ovsdb/ovsdb-idlc.in
ovsdb/ovsdb-server.c
ovsdb/row.c
ovsdb/server.c
ovsdb/table.c
ovsdb/transaction.c
ovsdb/trigger.c
python/ovs/socket_util.py
tests/automake.mk
tests/library.at
tests/odp.at
tests/ofproto-dpif.at
tests/ovs-vsctl.at
tests/test-hash.c
tests/test-util.c
utilities/ovs-ctl.in
utilities/ovs-dpctl.c
utilities/ovs-ofctl.c
utilities/ovs-save
utilities/ovs-vsctl.8.in
utilities/ovs-vsctl.c
vswitchd/bridge.c
vswitchd/ovs-vswitchd.c
vswitchd/system-stats.c

diff --git a/AUTHORS b/AUTHORS
index dc2b05c..28825d7 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -35,6 +35,7 @@ Henry Mai               hmai@nicira.com
 Hao Zheng               hzheng@nicira.com
 Ian Campbell            Ian.Campbell@citrix.com
 Isaku Yamahata          yamahata@valinux.co.jp
+James Page              james.page@ubuntu.com
 Jarno Rajahalme         jarno.rajahalme@nsn.com
 Jean Tourrilhes         jt@hpl.hp.com
 Jeremy Stribling        strib@nicira.com
@@ -52,7 +53,9 @@ Martin Casado           casado@nicira.com
 Mehak Mahajan           mmahajan@nicira.com
 Natasha Gude            natasha@nicira.com
 Neil McKee              neil.mckee@inmon.com
+Paraneetharan Chandrasekaran    paraneetharanc@gmail.com
 Paul Fazzone            pfazzone@nicira.com
+Pavithra Ramesh         paramesh@vmware.com
 Philippe Jung           phil.jung@free.fr
 Pravin B Shelar         pshelar@nicira.com
 Raju Subramanian        rsubramanian@nicira.com
diff --git a/FAQ b/FAQ
index 6d14fc8..72a1479 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -145,7 +145,7 @@ A: The following table lists the Linux kernel versions against which the
        1.6.x      2.6.18 to 3.2
        1.7.x      2.6.18 to 3.3
        1.8.x      2.6.18 to 3.4
-       1.9.x      2.6.18 to 3.7
+       1.9.x      2.6.18 to 3.8
 
    Open vSwitch userspace should also work with the Linux kernel module
    built into Linux 3.3 and later.
@@ -455,6 +455,110 @@ A: In version 1.9.0, OVS switched to using a single datapath that is
    commands provide similar functionality that is scoped by the bridge.
 
 
+Quality of Service (QoS)
+------------------------
+
+Q: How do I configure Quality of Service (QoS)?
+
+A: Suppose that you want to set up bridge br0 connected to physical
+   Ethernet port eth0 (a 1 Gbps device) and virtual machine interfaces
+   vif1.0 and vif2.0, and that you want to limit traffic from vif1.0
+   to eth0 to 10 Mbps and from vif2.0 to eth0 to 20 Mbps.  Then, you
+   could configure the bridge this way:
+
+       ovs-vsctl -- \
+           add-br br0 -- \
+          add-port br0 eth0 -- \
+          add-port br0 vif1.0 -- set interface vif1.0 ofport_request=5 -- \
+          add-port br0 vif2.0 -- set interface vif2.0 ofport_request=6 -- \
+          set port eth0 qos=@newqos -- \
+          --id=@newqos create qos type=linux-htb \
+               other-config:max-rate=1000000000 \
+              queues:123=@vif10queue \
+              queues:234=@vif20queue -- \
+           --id=@vif10queue create queue other-config:max-rate=10000000 -- \
+           --id=@vif20queue create queue other-config:max-rate=20000000
+
+   At this point, bridge br0 is configured with the ports and eth0 is
+   configured with the queues that you need for QoS, but nothing is
+   actually directing packets from vif1.0 or vif2.0 to the queues that
+   we have set up for them.  That means that all of the packets to
+   eth0 are going to the "default queue", which is not what we want.
+
+   We use OpenFlow to direct packets from vif1.0 and vif2.0 to the
+   queues reserved for them:
+
+       ovs-ofctl add-flow br0 in_port=5,actions=set_queue:123,normal
+       ovs-ofctl add-flow br0 in_port=6,actions=set_queue:234,normal
+
+   Each of the above flows matches on the input port, sets up the
+   appropriate queue (123 for vif1.0, 234 for vif2.0), and then
+   executes the "normal" action, which performs the same switching
+   that Open vSwitch would have done without any OpenFlow flows being
+   present.  (We know that vif1.0 and vif2.0 have OpenFlow port
+   numbers 5 and 6, respectively, because we set their ofport_request
+   columns above.  If we had not done that, then we would have needed
+   to find out their port numbers before setting up these flows.)
+
+   Now traffic going from vif1.0 or vif2.0 to eth0 should be
+   rate-limited.
+
+   By the way, if you delete the bridge created by the above commands,
+   with:
+
+       ovs-vsctl del-br br0
+
+   then that will leave one unreferenced QoS record and two
+   unreferenced Queue records in the Open vSwich database.  One way to
+   clear them out, assuming you don't have other QoS or Queue records
+   that you want to keep, is:
+
+       ovs-vsctl -- --all destroy QoS -- --all destroy Queue
+
+Q: I configured Quality of Service (QoS) in my OpenFlow network by
+   adding records to the QoS and Queue table, but the results aren't
+   what I expect.
+
+A: Did you install OpenFlow flows that use your queues?  This is the
+   primary way to tell Open vSwitch which queues you want to use.  If
+   you don't do this, then the default queue will be used, which will
+   probably not have the effect you want.
+
+   Refer to the previous question for an example.
+
+Q: I configured QoS, correctly, but my measurements show that it isn't
+   working as well as I expect.
+
+A: With the Linux kernel, the Open vSwitch implementation of QoS has
+   two aspects:
+
+       - Open vSwitch configures a subset of Linux kernel QoS
+         features, according to what is in OVSDB.  It is possible that
+         this code has bugs.  If you believe that this is so, then you
+         can configure the Linux traffic control (QoS) stack directly
+         with the "tc" program.  If you get better results that way,
+         you can send a detailed bug report to bugs@openvswitch.org.
+
+         It is certain that Open vSwitch cannot configure every Linux
+         kernel QoS feature.  If you need some feature that OVS cannot
+         configure, then you can also use "tc" directly (or add that
+         feature to OVS).
+
+       - The Open vSwitch implementation of OpenFlow allows flows to
+         be directed to particular queues.  This is pretty simple and
+         unlikely to have serious bugs at this point.
+
+   However, most problems with QoS on Linux are not bugs in Open
+   vSwitch at all.  They tend to be either configuration errors
+   (please see the earlier questions in this section) or issues with
+   the traffic control (QoS) stack in Linux.  The Open vSwitch
+   developers are not experts on Linux traffic control.  We suggest
+   that, if you believe you are encountering a problem with Linux
+   traffic control, that you consult the tc manpages (e.g. tc(8),
+   tc-htb(8), tc-hfsc(8)), web resources (e.g. http://lartc.org/), or
+   mailing lists (e.g. http://vger.kernel.org/vger-lists.html#netdev).
+
+
 VLANs
 -----
 
index 2c19618..bd5e2fc 100644 (file)
@@ -196,6 +196,19 @@ rate-limit-check:
         fi
 .PHONY: rate-limit-check
 
+# Check that assert.h is not used outside a whitelist of files.
+ALL_LOCAL += check-assert-h-usage
+check-assert-h-usage:
+       @if test -e $(srcdir)/.git && (git --version) >/dev/null 2>&1 && \
+           (cd $(srcdir) && git --no-pager grep -l -E '[<]assert.h[>]') | \
+           $(EGREP) -v '^lib/(sflow_receiver|vlog|worker).c$$|^tests/'; \
+         then \
+           echo "Files listed above unexpectedly #include <""assert.h"">."; \
+           echo "Please use ovs_assert (from util.h) instead of assert."; \
+           exit 1; \
+        fi
+.PHONY: check-assert-h-usage
+
 if HAVE_GROFF
 ALL_LOCAL += manpage-check
 manpage-check: $(man_MANS) $(dist_man_MANS) $(noinst_man_MANS)
diff --git a/NEWS b/NEWS
index f9f7171..6cf09ba 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,9 @@
 post-v1.9.0
 --------------------
+    - Bridge compatibility support has been removed.  Any uses that
+      rely on ovs-brcompatd will have to stick with Open vSwitch 1.9.x
+      or adapt to native Open vSwitch support (e.g. use ovs-vsctl instead
+      of brctl).
     - The maximum size of the MAC learning table is now configurable.
     - New support for the VXLAN tunnel protocol (see the IETF draft here:
       http://tools.ietf.org/html/draft-mahalingam-dutt-dcops-vxlan-02).
@@ -7,6 +11,8 @@ post-v1.9.0
       separately on a per-port basis, so it should no longer be
       possible for a large number of new flows arriving on one port to
       prevent new flows from being processed on other ports.
+    - Many "ovs-vsctl" database commands now accept an --if-exists option.
+      Please refer to the ovs-vsctl manpage for details.
     - New "vlog/disable-rate-limit" and "vlog/enable-rate-limit" commands
       available through ovs-appctl allow control over logging rate limits.
     - The OpenFlow "dp_desc" may now be configured by setting the value of 
@@ -29,7 +35,7 @@ v1.9.0 - xx xxx xxxx
     - Datapath:
       - Support for ipv6 set action.
       - SKB mark matching and setting.
-      - support for Linux kernels up to 3.7
+      - support for Linux kernels up to 3.8
     - FreeBSD is now a supported platform, thanks to code contributions from
       Gaetano Catalli, Ed Maste, and Giuseppe Lettieri.
     - ovs-bugtool: New --ovs option to report only OVS related information.
index 539d5e3..bcfb227 100644 (file)
@@ -27,6 +27,7 @@ AC_PROG_CPP
 AC_PROG_RANLIB
 AC_PROG_MKDIR_P
 AC_PROG_FGREP
+AC_PROG_EGREP
 
 AC_ARG_VAR([PERL], [path to Perl interpreter])
 AC_PATH_PROG([PERL], perl, no)
index ed69af8..b731c20 100644 (file)
@@ -61,8 +61,8 @@
 #include "vport-internal_dev.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \
-    LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
-#error Kernels before 2.6.18 or after 3.7 are not supported by this version of Open vSwitch.
+    LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+#error Kernels before 2.6.18 or after 3.8 are not supported by this version of Open vSwitch.
 #endif
 
 #define REHASH_FLOW_INTERVAL (10 * 60 * HZ)
@@ -423,16 +423,89 @@ static int flush_flows(struct datapath *dp)
        return 0;
 }
 
-static int validate_actions(const struct nlattr *attr,
-                               const struct sw_flow_key *key, int depth);
+static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa, int attr_len)
+{
+
+       struct sw_flow_actions *acts;
+       int new_acts_size;
+       int req_size = NLA_ALIGN(attr_len);
+       int next_offset = offsetof(struct sw_flow_actions, actions) +
+                                       (*sfa)->actions_len;
+
+       if (req_size <= (ksize(*sfa) - next_offset))
+               goto out;
+
+       new_acts_size = ksize(*sfa) * 2;
+
+       if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
+               if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size)
+                       return ERR_PTR(-EMSGSIZE);
+               new_acts_size = MAX_ACTIONS_BUFSIZE;
+       }
+
+       acts = ovs_flow_actions_alloc(new_acts_size);
+       if (IS_ERR(acts))
+               return (void *)acts;
+
+       memcpy(acts->actions, (*sfa)->actions, (*sfa)->actions_len);
+       acts->actions_len = (*sfa)->actions_len;
+       kfree(*sfa);
+       *sfa = acts;
+
+out:
+       (*sfa)->actions_len += req_size;
+       return  (struct nlattr *) ((unsigned char *)(*sfa) + next_offset);
+}
+
+static int add_action(struct sw_flow_actions **sfa, int attrtype, void *data, int len)
+{
+       struct nlattr *a;
+
+       a = reserve_sfa_size(sfa, nla_attr_size(len));
+       if (IS_ERR(a))
+               return PTR_ERR(a);
+
+       a->nla_type = attrtype;
+       a->nla_len = nla_attr_size(len);
+
+       if (data)
+               memcpy(nla_data(a), data, len);
+       memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len));
+
+       return 0;
+}
+
+static inline int add_nested_action_start(struct sw_flow_actions **sfa, int attrtype)
+{
+       int used = (*sfa)->actions_len;
+       int err;
+
+       err = add_action(sfa, attrtype, NULL, 0);
+       if (err)
+               return err;
+
+       return used;
+}
 
-static int validate_sample(const struct nlattr *attr,
-                               const struct sw_flow_key *key, int depth)
+static inline void add_nested_action_end(struct sw_flow_actions *sfa, int st_offset)
+{
+       struct nlattr *a = (struct nlattr *) ((unsigned char *)sfa->actions + st_offset);
+
+       a->nla_len = sfa->actions_len - st_offset;
+}
+
+static int validate_and_copy_actions(const struct nlattr *attr,
+                               const struct sw_flow_key *key, int depth,
+                               struct sw_flow_actions **sfa);
+
+static int validate_and_copy_sample(const struct nlattr *attr,
+                          const struct sw_flow_key *key, int depth,
+                          struct sw_flow_actions **sfa)
 {
        const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
        const struct nlattr *probability, *actions;
        const struct nlattr *a;
-       int rem;
+       int rem, start, err, st_acts;
 
        memset(attrs, 0, sizeof(attrs));
        nla_for_each_nested(a, attr, rem) {
@@ -451,7 +524,26 @@ static int validate_sample(const struct nlattr *attr,
        actions = attrs[OVS_SAMPLE_ATTR_ACTIONS];
        if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
                return -EINVAL;
-       return validate_actions(actions, key, depth + 1);
+
+       /* validation done, copy sample action. */
+       start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE);
+       if (start < 0)
+               return start;
+       err = add_action(sfa, OVS_SAMPLE_ATTR_PROBABILITY, nla_data(probability), sizeof(u32));
+       if (err)
+               return err;
+       st_acts = add_nested_action_start(sfa, OVS_SAMPLE_ATTR_ACTIONS);
+       if (st_acts < 0)
+               return st_acts;
+
+       err = validate_and_copy_actions(actions, key, depth + 1, sfa);
+       if (err)
+               return err;
+
+       add_nested_action_end(*sfa, st_acts);
+       add_nested_action_end(*sfa, start);
+
+       return 0;
 }
 
 static int validate_tp_port(const struct sw_flow_key *flow_key)
@@ -467,8 +559,30 @@ static int validate_tp_port(const struct sw_flow_key *flow_key)
        return -EINVAL;
 }
 
+static int validate_and_copy_set_tun(const struct nlattr *attr,
+                                    struct sw_flow_actions **sfa)
+{
+       struct ovs_key_ipv4_tunnel tun_key;
+       int err, start;
+
+       err = ipv4_tun_from_nlattr(nla_data(attr), &tun_key);
+       if (err)
+               return err;
+
+       start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET);
+       if (start < 0)
+               return start;
+
+       err = add_action(sfa, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key, sizeof(tun_key));
+       add_nested_action_end(*sfa, start);
+
+       return err;
+}
+
 static int validate_set(const struct nlattr *a,
-                       const struct sw_flow_key *flow_key)
+                       const struct sw_flow_key *flow_key,
+                       struct sw_flow_actions **sfa,
+                       bool *set_tun)
 {
        const struct nlattr *ovs_key = nla_data(a);
        int key_type = nla_type(ovs_key);
@@ -478,13 +592,14 @@ static int validate_set(const struct nlattr *a,
                return -EINVAL;
 
        if (key_type > OVS_KEY_ATTR_MAX ||
-           nla_len(ovs_key) != ovs_key_lens[key_type])
+           (ovs_key_lens[key_type] != nla_len(ovs_key) &&
+            ovs_key_lens[key_type] != -1))
                return -EINVAL;
 
        switch (key_type) {
        const struct ovs_key_ipv4 *ipv4_key;
-       const struct ovs_key_ipv4_tunnel *tun_key;
        const struct ovs_key_ipv6 *ipv6_key;
+       int err;
 
        case OVS_KEY_ATTR_PRIORITY:
        case OVS_KEY_ATTR_TUN_ID:
@@ -498,10 +613,11 @@ static int validate_set(const struct nlattr *a,
 #endif
                break;
 
-       case OVS_KEY_ATTR_IPV4_TUNNEL:
-               tun_key = nla_data(ovs_key);
-               if (!tun_key->ipv4_dst)
-                       return -EINVAL;
+       case OVS_KEY_ATTR_TUNNEL:
+               *set_tun = true;
+               err = validate_and_copy_set_tun(a, sfa);
+               if (err)
+                       return err;
                break;
 
        case OVS_KEY_ATTR_IPV4:
@@ -579,8 +695,24 @@ static int validate_userspace(const struct nlattr *attr)
        return 0;
 }
 
-static int validate_actions(const struct nlattr *attr,
-                               const struct sw_flow_key *key,  int depth)
+static int copy_action(const struct nlattr *from,
+                     struct sw_flow_actions **sfa)
+{
+       int totlen = NLA_ALIGN(from->nla_len);
+       struct nlattr *to;
+
+       to = reserve_sfa_size(sfa, from->nla_len);
+       if (IS_ERR(to))
+               return PTR_ERR(to);
+
+       memcpy(to, from, totlen);
+       return 0;
+}
+
+static int validate_and_copy_actions(const struct nlattr *attr,
+                               const struct sw_flow_key *key,
+                               int depth,
+                               struct sw_flow_actions **sfa)
 {
        const struct nlattr *a;
        int rem, err;
@@ -600,12 +732,14 @@ static int validate_actions(const struct nlattr *attr,
                };
                const struct ovs_action_push_vlan *vlan;
                int type = nla_type(a);
+               bool skip_copy;
 
                if (type > OVS_ACTION_ATTR_MAX ||
                    (action_lens[type] != nla_len(a) &&
                     action_lens[type] != (u32)-1))
                        return -EINVAL;
 
+               skip_copy = false;
                switch (type) {
                case OVS_ACTION_ATTR_UNSPEC:
                        return -EINVAL;
@@ -634,20 +768,26 @@ static int validate_actions(const struct nlattr *attr,
                        break;
 
                case OVS_ACTION_ATTR_SET:
-                       err = validate_set(a, key);
+                       err = validate_set(a, key, sfa, &skip_copy);
                        if (err)
                                return err;
                        break;
 
                case OVS_ACTION_ATTR_SAMPLE:
-                       err = validate_sample(a, key, depth);
+                       err = validate_and_copy_sample(a, key, depth, sfa);
                        if (err)
                                return err;
+                       skip_copy = true;
                        break;
 
                default:
                        return -EINVAL;
                }
+               if (!skip_copy) {
+                       err = copy_action(a, sfa);
+                       if (err)
+                               return err;
+               }
        }
 
        if (rem > 0)
@@ -716,16 +856,15 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
        err = ovs_flow_metadata_from_nlattrs(flow, key_len, a[OVS_PACKET_ATTR_KEY]);
        if (err)
                goto err_flow_free;
-
-       err = validate_actions(a[OVS_PACKET_ATTR_ACTIONS], &flow->key, 0);
-       if (err)
-               goto err_flow_free;
-
-       acts = ovs_flow_actions_alloc(a[OVS_PACKET_ATTR_ACTIONS]);
+       acts = ovs_flow_actions_alloc(nla_len(a[OVS_PACKET_ATTR_ACTIONS]));
        err = PTR_ERR(acts);
        if (IS_ERR(acts))
                goto err_flow_free;
+
+       err = validate_and_copy_actions(a[OVS_PACKET_ATTR_ACTIONS], &flow->key, 0, &acts);
        rcu_assign_pointer(flow->sf_acts, acts);
+       if (err)
+               goto err_flow_free;
 
        OVS_CB(packet)->flow = flow;
        packet->priority = flow->key.phy.priority;
@@ -814,6 +953,99 @@ static struct genl_multicast_group ovs_dp_flow_multicast_group = {
        .name = OVS_FLOW_MCGROUP
 };
 
+static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb);
+static int sample_action_to_attr(const struct nlattr *attr, struct sk_buff *skb)
+{
+       const struct nlattr *a;
+       struct nlattr *start;
+       int err = 0, rem;
+
+       start = nla_nest_start(skb, OVS_ACTION_ATTR_SAMPLE);
+       if (!start)
+               return -EMSGSIZE;
+
+       nla_for_each_nested(a, attr, rem) {
+               int type = nla_type(a);
+               struct nlattr *st_sample;
+
+               switch (type) {
+               case OVS_SAMPLE_ATTR_PROBABILITY:
+                       if (nla_put(skb, OVS_SAMPLE_ATTR_PROBABILITY, sizeof(u32), nla_data(a)))
+                               return -EMSGSIZE;
+                       break;
+               case OVS_SAMPLE_ATTR_ACTIONS:
+                       st_sample = nla_nest_start(skb, OVS_SAMPLE_ATTR_ACTIONS);
+                       if (!st_sample)
+                               return -EMSGSIZE;
+                       err = actions_to_attr(nla_data(a), nla_len(a), skb);
+                       if (err)
+                               return err;
+                       nla_nest_end(skb, st_sample);
+                       break;
+               }
+       }
+
+       nla_nest_end(skb, start);
+       return err;
+}
+
+static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
+{
+       const struct nlattr *ovs_key = nla_data(a);
+       int key_type = nla_type(ovs_key);
+       struct nlattr *start;
+       int err;
+
+       switch (key_type) {
+       case OVS_KEY_ATTR_IPV4_TUNNEL:
+               start = nla_nest_start(skb, OVS_ACTION_ATTR_SET);
+               if (!start)
+                       return -EMSGSIZE;
+
+               err = ipv4_tun_to_nlattr(skb, nla_data(ovs_key));
+               if (err)
+                       return err;
+               nla_nest_end(skb, start);
+               break;
+       default:
+               if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key))
+                       return -EMSGSIZE;
+               break;
+       }
+
+       return 0;
+}
+
+static int actions_to_attr(const struct nlattr *attr, int len, struct sk_buff *skb)
+{
+       const struct nlattr *a;
+       int rem, err;
+
+       nla_for_each_attr(a, attr, len, rem) {
+               int type = nla_type(a);
+
+               switch (type) {
+               case OVS_ACTION_ATTR_SET:
+                       err = set_action_to_attr(a, skb);
+                       if (err)
+                               return err;
+                       break;
+
+               case OVS_ACTION_ATTR_SAMPLE:
+                       err = sample_action_to_attr(a, skb);
+                       if (err)
+                               return err;
+                       break;
+               default:
+                       if (nla_put(skb, type, nla_len(a), nla_data(a)))
+                               return -EMSGSIZE;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
 /* Called with genl_lock. */
 static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
                                  struct sk_buff *skb, u32 portid,
@@ -821,6 +1053,7 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
 {
        const int skb_orig_len = skb->len;
        const struct sw_flow_actions *sf_acts;
+       struct nlattr *start;
        struct ovs_flow_stats stats;
        struct ovs_header *ovs_header;
        struct nlattr *nla;
@@ -875,10 +1108,19 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp,
         * This can only fail for dump operations because the skb is always
         * properly sized for single flows.
         */
-       err = nla_put(skb, OVS_FLOW_ATTR_ACTIONS, sf_acts->actions_len,
-                     sf_acts->actions);
-       if (err < 0 && skb_orig_len)
-               goto error;
+       start = nla_nest_start(skb, OVS_FLOW_ATTR_ACTIONS);
+       if (start) {
+               err = actions_to_attr(sf_acts->actions, sf_acts->actions_len, skb);
+               if (!err)
+                       nla_nest_end(skb, start);
+               else {
+                       if (skb_orig_len)
+                               goto error;
+
+                       nla_nest_cancel(skb, start);
+               }
+       } else if (skb_orig_len)
+               goto nla_put_failure;
 
        return genlmsg_end(skb, ovs_header);
 
@@ -938,6 +1180,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
        struct sk_buff *reply;
        struct datapath *dp;
        struct flow_table *table;
+       struct sw_flow_actions *acts = NULL;
        int error;
        int key_len;
 
@@ -951,9 +1194,14 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 
        /* Validate actions. */
        if (a[OVS_FLOW_ATTR_ACTIONS]) {
-               error = validate_actions(a[OVS_FLOW_ATTR_ACTIONS], &key,  0);
-               if (error)
+               acts = ovs_flow_actions_alloc(nla_len(a[OVS_FLOW_ATTR_ACTIONS]));
+               error = PTR_ERR(acts);
+               if (IS_ERR(acts))
                        goto error;
+
+               error = validate_and_copy_actions(a[OVS_FLOW_ATTR_ACTIONS], &key,  0, &acts);
+               if (error)
+                       goto err_kfree;
        } else if (info->genlhdr->cmd == OVS_FLOW_CMD_NEW) {
                error = -EINVAL;
                goto error;
@@ -962,17 +1210,15 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
        dp = get_dp(sock_net(skb->sk), ovs_header->dp_ifindex);
        error = -ENODEV;
        if (!dp)
-               goto error;
+               goto err_kfree;
 
        table = genl_dereference(dp->table);
        flow = ovs_flow_tbl_lookup(table, &key, key_len);
        if (!flow) {
-               struct sw_flow_actions *acts;
-
                /* Bail out if we're not allowed to create a new flow. */
                error = -ENOENT;
                if (info->genlhdr->cmd == OVS_FLOW_CMD_SET)
-                       goto error;
+                       goto err_kfree;
 
                /* Expand table, if necessary, to make room. */
                if (ovs_flow_tbl_need_to_expand(table)) {
@@ -990,15 +1236,10 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                flow = ovs_flow_alloc();
                if (IS_ERR(flow)) {
                        error = PTR_ERR(flow);
-                       goto error;
+                       goto err_kfree;
                }
                clear_stats(flow);
 
-               /* Obtain actions. */
-               acts = ovs_flow_actions_alloc(a[OVS_FLOW_ATTR_ACTIONS]);
-               error = PTR_ERR(acts);
-               if (IS_ERR(acts))
-                       goto error_free_flow;
                rcu_assign_pointer(flow->sf_acts, acts);
 
                /* Put flow in bucket. */
@@ -1010,7 +1251,6 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
        } else {
                /* We found a matching flow. */
                struct sw_flow_actions *old_acts;
-               struct nlattr *acts_attrs;
 
                /* Bail out if we're not allowed to modify an existing flow.
                 * We accept NLM_F_CREATE in place of the intended NLM_F_EXCL
@@ -1021,26 +1261,13 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                error = -EEXIST;
                if (info->genlhdr->cmd == OVS_FLOW_CMD_NEW &&
                    info->nlhdr->nlmsg_flags & (NLM_F_CREATE | NLM_F_EXCL))
-                       goto error;
+                       goto err_kfree;
 
                /* Update actions. */
                old_acts = rcu_dereference_protected(flow->sf_acts,
                                                     lockdep_genl_is_held());
-               acts_attrs = a[OVS_FLOW_ATTR_ACTIONS];
-               if (acts_attrs &&
-                  (old_acts->actions_len != nla_len(acts_attrs) ||
-                  memcmp(old_acts->actions, nla_data(acts_attrs),
-                         old_acts->actions_len))) {
-                       struct sw_flow_actions *new_acts;
-
-                       new_acts = ovs_flow_actions_alloc(acts_attrs);
-                       error = PTR_ERR(new_acts);
-                       if (IS_ERR(new_acts))
-                               goto error;
-
-                       rcu_assign_pointer(flow->sf_acts, new_acts);
-                       ovs_flow_deferred_free_acts(old_acts);
-               }
+               rcu_assign_pointer(flow->sf_acts, acts);
+               ovs_flow_deferred_free_acts(old_acts);
 
                reply = ovs_flow_cmd_build_info(flow, dp, info->snd_portid,
                                               info->snd_seq, OVS_FLOW_CMD_NEW);
@@ -1062,8 +1289,8 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
                                ovs_dp_flow_multicast_group.id, PTR_ERR(reply));
        return 0;
 
-error_free_flow:
-       ovs_flow_free(flow);
+err_kfree:
+       kfree(acts);
 error:
        return error;
 }
index 63eef77..fad9e19 100644 (file)
@@ -200,20 +200,18 @@ void ovs_flow_used(struct sw_flow *flow, struct sk_buff *skb)
        spin_unlock(&flow->lock);
 }
 
-struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *actions)
+struct sw_flow_actions *ovs_flow_actions_alloc(int size)
 {
-       int actions_len = nla_len(actions);
        struct sw_flow_actions *sfa;
 
-       if (actions_len > MAX_ACTIONS_BUFSIZE)
+       if (size > MAX_ACTIONS_BUFSIZE)
                return ERR_PTR(-EINVAL);
 
-       sfa = kmalloc(sizeof(*sfa) + actions_len, GFP_KERNEL);
+       sfa = kmalloc(sizeof(*sfa) + size, GFP_KERNEL);
        if (!sfa)
                return ERR_PTR(-ENOMEM);
 
-       sfa->actions_len = actions_len;
-       memcpy(sfa->actions, nla_data(actions), actions_len);
+       sfa->actions_len = 0;
        return sfa;
 }
 
@@ -848,7 +846,7 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
        [OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6),
        [OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp),
        [OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd),
-       [OVS_KEY_ATTR_IPV4_TUNNEL] = sizeof(struct ovs_key_ipv4_tunnel),
+       [OVS_KEY_ATTR_TUNNEL] = -1,
 
        /* Not upstream. */
        [OVS_KEY_ATTR_TUN_ID] = sizeof(__be64),
@@ -989,6 +987,105 @@ static int parse_flow_nlattrs(const struct nlattr *attr,
        return 0;
 }
 
+int ipv4_tun_from_nlattr(const struct nlattr *attr,
+                        struct ovs_key_ipv4_tunnel *tun_key)
+{
+       struct nlattr *a;
+       int rem;
+       bool ttl = false;
+
+       memset(tun_key, 0, sizeof(*tun_key));
+
+       nla_for_each_nested(a, attr, rem) {
+               int type = nla_type(a);
+               static const u32 ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
+                       [OVS_TUNNEL_KEY_ATTR_ID] = sizeof(u64),
+                       [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = sizeof(u32),
+                       [OVS_TUNNEL_KEY_ATTR_IPV4_DST] = sizeof(u32),
+                       [OVS_TUNNEL_KEY_ATTR_TOS] = 1,
+                       [OVS_TUNNEL_KEY_ATTR_TTL] = 1,
+                       [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = 0,
+                       [OVS_TUNNEL_KEY_ATTR_CSUM] = 0,
+               };
+
+               if (type > OVS_TUNNEL_KEY_ATTR_MAX ||
+                       ovs_tunnel_key_lens[type] != nla_len(a))
+                       return -EINVAL;
+
+               switch (type) {
+               case OVS_TUNNEL_KEY_ATTR_ID:
+                       tun_key->tun_id = nla_get_be64(a);
+                       tun_key->tun_flags |= OVS_TNL_F_KEY;
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
+                       tun_key->ipv4_src = nla_get_be32(a);
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
+                       tun_key->ipv4_dst = nla_get_be32(a);
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_TOS:
+                       tun_key->ipv4_tos = nla_get_u8(a);
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_TTL:
+                       tun_key->ipv4_ttl = nla_get_u8(a);
+                       ttl = true;
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
+                       tun_key->tun_flags |= OVS_TNL_F_DONT_FRAGMENT;
+                       break;
+               case OVS_TUNNEL_KEY_ATTR_CSUM:
+                       tun_key->tun_flags |= OVS_TNL_F_CSUM;
+                       break;
+               default:
+                       return -EINVAL;
+
+               }
+       }
+       if (rem > 0)
+               return -EINVAL;
+
+       if (!tun_key->ipv4_dst)
+               return -EINVAL;
+
+       if (!ttl)
+               return -EINVAL;
+
+       return 0;
+}
+
+int ipv4_tun_to_nlattr(struct sk_buff *skb,
+                       const struct ovs_key_ipv4_tunnel *tun_key)
+{
+       struct nlattr *nla;
+
+       nla = nla_nest_start(skb, OVS_KEY_ATTR_TUNNEL);
+       if (!nla)
+               return -EMSGSIZE;
+
+       if (tun_key->tun_flags & OVS_TNL_F_KEY &&
+           nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, tun_key->tun_id))
+               return -EMSGSIZE;
+       if (tun_key->ipv4_src &&
+           nla_put_be32(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tun_key->ipv4_src))
+               return -EMSGSIZE;
+       if (nla_put_be32(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST, tun_key->ipv4_dst))
+               return -EMSGSIZE;
+       if (tun_key->ipv4_tos &&
+           nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, tun_key->ipv4_tos))
+               return -EMSGSIZE;
+       if (nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TTL, tun_key->ipv4_ttl))
+               return -EMSGSIZE;
+       if ((tun_key->tun_flags & OVS_TNL_F_DONT_FRAGMENT) &&
+               nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT))
+               return -EMSGSIZE;
+       if ((tun_key->tun_flags & OVS_TNL_F_CSUM) &&
+               nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM))
+               return -EMSGSIZE;
+
+       nla_nest_end(skb, nla);
+       return 0;
+}
+
 /**
  * ovs_flow_from_nlattrs - parses Netlink attributes into a flow key.
  * @swkey: receives the extracted flow key.
@@ -1037,37 +1134,29 @@ int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
        }
 
        if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID) &&
-           attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
-               struct ovs_key_ipv4_tunnel *tun_key;
+           attrs & (1ULL << OVS_KEY_ATTR_TUNNEL)) {
                __be64 tun_id;
 
-               tun_key = nla_data(a[OVS_KEY_ATTR_IPV4_TUNNEL]);
+               err = ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], &swkey->tun_key);
+               if (err)
+                       return err;
 
-               if (!tun_key->ipv4_dst)
-                       return -EINVAL;
-               if (!(tun_key->tun_flags & OVS_TNL_F_KEY))
+               if (!(swkey->tun_key.tun_flags & OVS_TNL_F_KEY))
                        return -EINVAL;
 
                tun_id = nla_get_be64(a[OVS_KEY_ATTR_TUN_ID]);
-               if (tun_id != tun_key->tun_id)
+               if (tun_id != swkey->tun_key.tun_id)
                        return -EINVAL;
 
-               memcpy(&swkey->tun_key, tun_key, sizeof(swkey->tun_key));
-               memset(swkey->tun_key.pad, 0, sizeof(swkey->tun_key.pad));
-
                attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
-               attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
-       } else if (attrs & (1ULL << OVS_KEY_ATTR_IPV4_TUNNEL)) {
-               struct ovs_key_ipv4_tunnel *tun_key;
-               tun_key = nla_data(a[OVS_KEY_ATTR_IPV4_TUNNEL]);
-
-               if (!tun_key->ipv4_dst)
-                       return -EINVAL;
+               attrs &= ~(1ULL << OVS_KEY_ATTR_TUNNEL);
+       } else if (attrs & (1ULL << OVS_KEY_ATTR_TUNNEL)) {
 
-               memcpy(&swkey->tun_key, tun_key, sizeof(swkey->tun_key));
-               memset(swkey->tun_key.pad, 0, sizeof(swkey->tun_key.pad));
+               err = ipv4_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], &swkey->tun_key);
+               if (err)
+                       return err;
 
-               attrs &= ~(1ULL << OVS_KEY_ATTR_IPV4_TUNNEL);
+               attrs &= ~(1ULL << OVS_KEY_ATTR_TUNNEL);
        }
 
        /* Data attributes. */
@@ -1223,6 +1312,8 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const stru
                int type = nla_type(nla);
 
                if (type <= OVS_KEY_ATTR_MAX && ovs_key_lens[type] > 0) {
+                       int err;
+
                        if (nla_len(nla) != ovs_key_lens[type])
                                return -EINVAL;
 
@@ -1246,21 +1337,23 @@ int ovs_flow_metadata_from_nlattrs(struct sw_flow *flow, int key_len, const stru
 
                                break;
 
-                       case OVS_KEY_ATTR_IPV4_TUNNEL:
+                       case OVS_KEY_ATTR_TUNNEL:
                                if (tun_key->tun_flags & OVS_TNL_F_KEY) {
                                        tun_id = tun_key->tun_id;
+                                       err = ipv4_tun_from_nlattr(nla, tun_key);
+                                       if (err)
+                                               return err;
 
-                                       memcpy(tun_key, nla_data(nla), sizeof(*tun_key));
                                        if (!(tun_key->tun_flags & OVS_TNL_F_KEY))
                                                return -EINVAL;
 
                                        if (tun_key->tun_id != tun_id)
                                                return -EINVAL;
-                               } else
-                                       memcpy(tun_key, nla_data(nla), sizeof(*tun_key));
-
-                               if (!tun_key->ipv4_dst)
-                                       return -EINVAL;
+                               } else {
+                                       err = ipv4_tun_from_nlattr(nla, tun_key);
+                                       if (err)
+                                               return err;
+                               }
                                break;
 
                        case OVS_KEY_ATTR_IN_PORT:
@@ -1297,14 +1390,10 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
            nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority))
                goto nla_put_failure;
 
-       if (swkey->tun_key.ipv4_dst) {
-               struct ovs_key_ipv4_tunnel *tun_key;
-               nla = nla_reserve(skb, OVS_KEY_ATTR_IPV4_TUNNEL, sizeof(*tun_key));
-               if (!nla)
-                       goto nla_put_failure;
-               tun_key = nla_data(nla);
-               memcpy(tun_key, &swkey->tun_key, sizeof(*tun_key));
-       }
+       if (swkey->tun_key.ipv4_dst &&
+           ipv4_tun_to_nlattr(skb, &swkey->tun_key))
+               goto nla_put_failure;
+
        if ((swkey->tun_key.tun_flags & OVS_TNL_F_KEY) &&
            nla_put_be64(skb, OVS_KEY_ATTR_TUN_ID, swkey->tun_key.tun_id))
                goto nla_put_failure;
index 3f3624f..dab6980 100644 (file)
@@ -40,6 +40,20 @@ struct sw_flow_actions {
        struct nlattr actions[];
 };
 
+/* Tunnel flow flags. */
+#define OVS_TNL_F_DONT_FRAGMENT                (1 << 0)
+#define OVS_TNL_F_CSUM                 (1 << 1)
+#define OVS_TNL_F_KEY                  (1 << 2)
+
+struct ovs_key_ipv4_tunnel {
+       __be64 tun_id;
+       __be32 ipv4_src;
+       __be32 ipv4_dst;
+       u16  tun_flags;
+       u8   ipv4_tos;
+       u8   ipv4_ttl;
+};
+
 struct sw_flow_key {
        struct ovs_key_ipv4_tunnel tun_key;  /* Encapsulating tunnel key. */
        struct {
@@ -131,7 +145,7 @@ struct sw_flow *ovs_flow_alloc(void);
 void ovs_flow_deferred_free(struct sw_flow *);
 void ovs_flow_free(struct sw_flow *);
 
-struct sw_flow_actions *ovs_flow_actions_alloc(const struct nlattr *);
+struct sw_flow_actions *ovs_flow_actions_alloc(int actions_len);
 void ovs_flow_deferred_free_acts(struct sw_flow_actions *);
 
 int ovs_flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *,
@@ -142,25 +156,32 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies);
 /* Upper bound on the length of a nlattr-formatted flow key.  The longest
  * nlattr-formatted flow key would be:
  *
- *                         struct  pad  nl hdr  total
- *                         ------  ---  ------  -----
- *  OVS_KEY_ATTR_PRIORITY      4    --     4      8
- *  OVS_KEY_ATTR_TUN_ID        8    --     4     12
- *  OVS_KEY_ATTR_IPV4_TUNNEL  24    --     4     28
- *  OVS_KEY_ATTR_IN_PORT       4    --     4      8
- *  OVS_KEY_ATTR_SKB_MARK      4    --     4      8
- *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
- *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (outer VLAN ethertype)
- *  OVS_KEY_ATTR_8021Q         4    --     4      8
- *  OVS_KEY_ATTR_ENCAP         0    --     4      4  (VLAN encapsulation)
- *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (inner VLAN ethertype)
- *  OVS_KEY_ATTR_IPV6         40    --     4     44
- *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
- *  OVS_KEY_ATTR_ND           28    --     4     32
- *  -------------------------------------------------
- *  total                                       192
+ *                                     struct  pad  nl hdr  total
+ *                                     ------  ---  ------  -----
+ *  OVS_KEY_ATTR_PRIORITY                4    --     4      8
+ *  OVS_KEY_ATTR_TUN_ID                  8    --     4     12
+ *  OVS_KEY_ATTR_TUNNEL                  0    --     4      4
+ *  - OVS_TUNNEL_KEY_ATTR_ID             8    --     4     12
+ *  - OVS_TUNNEL_KEY_ATTR_IPV4_SRC       4    --     4      8
+ *  - OVS_TUNNEL_KEY_ATTR_IPV4_DST       4    --     4      8
+ *  - OVS_TUNNEL_KEY_ATTR_TOS            1    3      4      8
+ *  - OVS_TUNNEL_KEY_ATTR_TTL            1    3      4      8
+ *  - OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT  0    --     4      4
+ *  - OVS_TUNNEL_KEY_ATTR_CSUM           0    --     4      4
+ *  OVS_KEY_ATTR_IN_PORT                 4    --     4      8
+ *  OVS_KEY_ATTR_SKB_MARK                4    --     4      8
+ *  OVS_KEY_ATTR_ETHERNET               12    --     4     16
+ *  OVS_KEY_ATTR_ETHERTYPE               2     2     4      8  (outer VLAN ethertype)
+ *  OVS_KEY_ATTR_8021Q                   4    --     4      8
+ *  OVS_KEY_ATTR_ENCAP                   0    --     4      4  (VLAN encapsulation)
+ *  OVS_KEY_ATTR_ETHERTYPE               2     2     4      8  (inner VLAN ethertype)
+ *  OVS_KEY_ATTR_IPV6                   40    --     4     44
+ *  OVS_KEY_ATTR_ICMPV6                  2     2     4      8
+ *  OVS_KEY_ATTR_ND                     28    --     4     32
+ *  ----------------------------------------------------------
+ *  total                                                 220
  */
-#define FLOW_BUFSIZE 192
+#define FLOW_BUFSIZE 220
 
 int ovs_flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
 int ovs_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
@@ -203,5 +224,9 @@ void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow);
 
 struct sw_flow *ovs_flow_tbl_next(struct flow_table *table, u32 *bucket, u32 *idx);
 extern const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1];
+int ipv4_tun_from_nlattr(const struct nlattr *attr,
+                        struct ovs_key_ipv4_tunnel *tun_key);
+int ipv4_tun_to_nlattr(struct sk_buff *skb,
+                       const struct ovs_key_ipv4_tunnel *tun_key);
 
 #endif /* flow.h */
index 7705475..b7de7a9 100644 (file)
@@ -201,7 +201,6 @@ static inline void tnl_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key,
        tun_key->ipv4_tos = iph->tos;
        tun_key->ipv4_ttl = iph->ttl;
        tun_key->tun_flags = tun_flags;
-       memset(tun_key->pad, 0, sizeof(tun_key->pad));
 }
 
 static inline void tnl_get_param(const struct tnl_mutable_config *mutable,
index 78f1493..fb64fe0 100644 (file)
@@ -225,10 +225,11 @@ int ovs_netdev_get_ifindex(const struct vport *vport)
 /* Must be called with rcu_read_lock. */
 static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 {
-       if (unlikely(!vport)) {
-               kfree_skb(skb);
-               return;
-       }
+       if (unlikely(!vport))
+               goto error;
+
+       if (unlikely(skb_warn_if_lro(skb)))
+               goto error;
 
        /* Make our own copy of the packet.  Otherwise we will mangle the
         * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
@@ -240,13 +241,16 @@ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
 
        skb_push(skb, ETH_HLEN);
 
-       if (unlikely(compute_ip_summed(skb, false))) {
-               kfree_skb(skb);
-               return;
-       }
+       if (unlikely(compute_ip_summed(skb, false)))
+               goto error;
+
        vlan_copy_skb_tci(skb);
 
        ovs_vport_receive(vport, skb);
+       return;
+
+error:
+       kfree_skb(skb);
 }
 
 static unsigned int packet_length(const struct sk_buff *skb)
@@ -285,9 +289,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
                goto error;
        }
 
-       if (unlikely(skb_warn_if_lro(skb)))
-               goto error;
-
        skb->dev = netdev_vport->dev;
        forward_ip_summed(skb, true);
 
index 41c3b94..d3a8faf 100644 (file)
@@ -14,7 +14,7 @@ openvswitch (1.9.0-1) unstable; urgency=low
     - Datapath:
       - Support for ipv6 set action.
       - SKB mark matching and setting.
-      - support for Linux kernels up to 3.7
+      - support for Linux kernels up to 3.8
     - FreeBSD is now a supported platform, thanks to code contributions from
       Gaetano Catalli, Ed Maste, and Giuseppe Lettieri.
     - ovs-bugtool: New --ovs option to report only OVS related information.
index 2ed4753..3ed4800 100755 (executable)
@@ -7,17 +7,21 @@ set -e
 
 #DEBHELPER#
 
-# If the switch is running, restart it.  This ensures that we are using the
-# latest kernel module, because the init script will unload and reload the
-# module.
+# If the kernel module is already loaded, we have nothing to do here.
+# A force-reload-kmod should be run manually to use the new kernel module.
+if [ -e /sys/module/openvswitch ] || [ -e /sys/module/openvswitch_mod ]; then
+    exit 0
+fi
+
+# If the kernel module is not loaded, then it is likely because none
+# was installed before and therefore Open vSwitch couldn't be started.
+# Try to start it now.
 #
 # (Ideally we'd only want to do this if this package corresponds to the
 # running kernel, but I don't know a reliable way to check.)
 INIT=/etc/init.d/openvswitch-switch
-if test -x $INIT && $INIT status; then
-    $INIT restart || true
+if test -x $INIT; then
+    $INIT start || true
 fi
 
 exit 0
-
-
index 5e32965..f471fbc 100644 (file)
@@ -282,13 +282,30 @@ enum ovs_key_attr {
        OVS_KEY_ATTR_ARP,       /* struct ovs_key_arp */
        OVS_KEY_ATTR_ND,        /* struct ovs_key_nd */
        OVS_KEY_ATTR_SKB_MARK,  /* u32 skb mark */
+       OVS_KEY_ATTR_TUNNEL,    /* Nested set of ovs_tunnel attributes */
+
+#ifdef __KERNEL__
        OVS_KEY_ATTR_IPV4_TUNNEL,  /* struct ovs_key_ipv4_tunnel */
+#endif
        OVS_KEY_ATTR_TUN_ID = 63,  /* be64 tunnel ID */
        __OVS_KEY_ATTR_MAX
 };
 
 #define OVS_KEY_ATTR_MAX (__OVS_KEY_ATTR_MAX - 1)
 
+enum ovs_tunnel_key_attr {
+       OVS_TUNNEL_KEY_ATTR_ID,                 /* be64 Tunnel ID */
+       OVS_TUNNEL_KEY_ATTR_IPV4_SRC,           /* be32 src IP address. */
+       OVS_TUNNEL_KEY_ATTR_IPV4_DST,           /* be32 dst IP address. */
+       OVS_TUNNEL_KEY_ATTR_TOS,                /* u8 Tunnel IP ToS. */
+       OVS_TUNNEL_KEY_ATTR_TTL,                /* u8 Tunnel IP TTL. */
+       OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT,      /* No argument, set DF. */
+       OVS_TUNNEL_KEY_ATTR_CSUM,               /* No argument. CSUM packet. */
+       __OVS_TUNNEL_KEY_ATTR_MAX
+};
+
+#define OVS_TUNNEL_KEY_ATTR_MAX (__OVS_TUNNEL_KEY_ATTR_MAX - 1)
+
 /**
  * enum ovs_frag_type - IPv4 and IPv6 fragment type
  * @OVS_FRAG_TYPE_NONE: Packet is not a fragment.
@@ -365,21 +382,6 @@ struct ovs_key_nd {
        __u8  nd_tll[6];
 };
 
-/* Values for ovs_key_ipv4_tunnel->tun_flags */
-#define OVS_TNL_F_DONT_FRAGMENT (1 << 0)
-#define OVS_TNL_F_CSUM (1 << 1)
-#define OVS_TNL_F_KEY (1 << 2)
-
-struct ovs_key_ipv4_tunnel {
-       __be64 tun_id;
-       __u32  tun_flags;
-       __be32 ipv4_src;
-       __be32 ipv4_dst;
-       __u8   ipv4_tos;
-       __u8   ipv4_ttl;
-       __u8   pad[2];
-};
-
 /**
  * enum ovs_flow_attr - attributes for %OVS_FLOW_* commands.
  * @OVS_FLOW_ATTR_KEY: Nested %OVS_KEY_ATTR_* attributes specifying the flow
index b95cc56..9d8d2fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Nicira, Inc.
+ * Copyright (c) 2009, 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.
@@ -26,8 +26,6 @@
 
 #include "aes128.h"
 
-#include <assert.h>
-
 #include "util.h"
 
 static const uint32_t Te0[256] = {
@@ -748,7 +746,7 @@ aes128_schedule(struct aes128 *aes, const uint8_t key[16])
         rk[6] = rk[2] ^ rk[5];
         rk[7] = rk[3] ^ rk[6];
     }
-    assert(rk == &aes->rk[40]);
+    ovs_assert(rk == &aes->rk[40]);
 }
 
 void
index 8d148ca..185f092 100644 (file)
@@ -61,6 +61,8 @@ lib_libopenvswitch_a_SOURCES = \
        lib/hmap.h \
        lib/hmapx.c \
        lib/hmapx.h \
+       lib/jhash.c \
+       lib/jhash.h \
        lib/json.c \
        lib/json.h \
        lib/jsonrpc.c \
index c05e0c8..06680ee 100644 (file)
@@ -533,7 +533,7 @@ bond_compose_learning_packet(struct bond *bond,
     tag_type tags = 0;
     struct flow flow;
 
-    assert(may_send_learning_packets(bond));
+    ovs_assert(may_send_learning_packets(bond));
 
     memset(&flow, 0, sizeof flow);
     memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN);
@@ -1373,7 +1373,7 @@ bond_hash_tcp(const struct flow *flow, uint16_t vlan, uint32_t basis)
 static unsigned int
 bond_hash(const struct bond *bond, const struct flow *flow, uint16_t vlan)
 {
-    assert(bond->balance == BM_TCP || bond->balance == BM_SLB);
+    ovs_assert(bond->balance == BM_TCP || bond->balance == BM_SLB);
 
     return (bond->balance == BM_TCP
             ? bond_hash_tcp(flow, vlan, bond->basis)
index c43dff7..2ee4a65 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2009 Nicira, Inc.
+/* Copyright (c) 2008, 2009, 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.
@@ -15,7 +15,6 @@
 
 #include <config.h>
 #include "byteq.h"
-#include <assert.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
@@ -65,7 +64,7 @@ byteq_is_full(const struct byteq *q)
 void
 byteq_put(struct byteq *q, uint8_t c)
 {
-    assert(!byteq_is_full(q));
+    ovs_assert(!byteq_is_full(q));
     *byteq_head(q) = c;
     q->head++;
 }
@@ -76,7 +75,7 @@ void
 byteq_putn(struct byteq *q, const void *p_, size_t n)
 {
     const uint8_t *p = p_;
-    assert(byteq_avail(q) >= n);
+    ovs_assert(byteq_avail(q) >= n);
     while (n > 0) {
         size_t chunk = MIN(n, byteq_headroom(q));
         memcpy(byteq_head(q), p, chunk);
@@ -100,7 +99,7 @@ uint8_t
 byteq_get(struct byteq *q)
 {
     uint8_t c;
-    assert(!byteq_is_empty(q));
+    ovs_assert(!byteq_is_empty(q));
     c = *byteq_tail(q);
     q->tail++;
     return c;
@@ -117,7 +116,7 @@ byteq_write(struct byteq *q, int fd)
         if (n > 0) {
             byteq_advance_tail(q, n);
         } else {
-            assert(n < 0);
+            ovs_assert(n < 0);
             return errno;
         }
     }
@@ -165,7 +164,7 @@ byteq_tail(const struct byteq *q)
 void
 byteq_advance_tail(struct byteq *q, unsigned int n)
 {
-    assert(byteq_tailroom(q) >= n);
+    ovs_assert(byteq_tailroom(q) >= n);
     q->tail += n;
 }
 
@@ -192,6 +191,6 @@ byteq_headroom(const struct byteq *q)
 void
 byteq_advance_head(struct byteq *q, unsigned int n)
 {
-    assert(byteq_headroom(q) >= n);
+    ovs_assert(byteq_headroom(q) >= n);
     q->head += n;
 }
index b71c242..d232b34 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "cfm.h"
 
-#include <assert.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -190,7 +189,7 @@ cfm_generate_maid(struct cfm *cfm)
     md_len = strlen(ovs_md_name);
     ma_len = strlen(ovs_ma_name);
 
-    assert(md_len && ma_len && md_len + ma_len + 4 <= CCM_MAID_LEN);
+    ovs_assert(md_len && ma_len && md_len + ma_len + 4 <= CCM_MAID_LEN);
 
     cfm->maid[0] = 4;                           /* MD name string format. */
     cfm->maid[1] = md_len;                      /* MD name size. */
@@ -368,7 +367,7 @@ cfm_run(struct cfm *cfm)
                 cfm->health = (rmp->num_health_ccm * 100) / exp_ccm_recvd;
                 cfm->health = MIN(cfm->health, 100);
                 rmp->num_health_ccm = 0;
-                assert(cfm->health >= 0 && cfm->health <= 100);
+                ovs_assert(cfm->health >= 0 && cfm->health <= 100);
             }
             cfm->health_interval = 0;
         }
@@ -466,7 +465,7 @@ cfm_compose_ccm(struct cfm *cfm, struct ofpbuf *packet,
     }
 
     if (cfm->ccm_interval == 0) {
-        assert(cfm->extended);
+        ovs_assert(cfm->extended);
         ccm->interval_ms_x = htons(cfm->ccm_interval_ms);
     } else {
         ccm->interval_ms_x = htons(0);
index d1fe524..7192602 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "classifier.h"
-#include <assert.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include "byte-order.h"
@@ -208,7 +207,7 @@ void
 classifier_insert(struct classifier *cls, struct cls_rule *rule)
 {
     struct cls_rule *displaced_rule = classifier_replace(cls, rule);
-    assert(!displaced_rule);
+    ovs_assert(!displaced_rule);
 }
 
 /* Removes 'rule' from 'cls'.  It is the caller's responsibility to destroy
index 27612a7..760389d 100644 (file)
@@ -26,6 +26,8 @@
 #define ALWAYS_INLINE __attribute__((always_inline))
 #define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
 #define SENTINEL(N) __attribute__((sentinel(N)))
+#define OVS_LIKELY(CONDITION) __builtin_expect(!!(CONDITION), 1)
+#define OVS_UNLIKELY(CONDITION) __builtin_expect(!!(CONDITION), 0)
 #else
 #define NO_RETURN
 #define OVS_UNUSED
@@ -35,6 +37,8 @@
 #define ALWAYS_INLINE
 #define WARN_UNUSED_RESULT
 #define SENTINEL(N)
+#define OVS_LIKELY(CONDITION) (!!(CONDITION))
+#define OVS_UNLIKELY(CONDITION) (!!(CONDITION))
 #endif
 
 /* ISO C says that a C implementation may choose any integer type for an enum
index 4849196..e7ee56c 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "daemon.h"
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -158,7 +157,9 @@ daemon_set_monitor(void)
 void
 daemon_save_fd(int fd)
 {
-    assert(fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO);
+    ovs_assert(fd == STDIN_FILENO ||
+               fd == STDOUT_FILENO ||
+               fd == STDERR_FILENO);
     save_fds[fd] = true;
 }
 
index 63d7afb..4425f6f 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "dpif-linux.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -475,9 +474,11 @@ dpif_linux_port_add(struct dpif *dpif_, struct netdev *netdev,
         *port_nop = reply.port_no;
         VLOG_DBG("%s: assigning port %"PRIu32" to netlink pid %"PRIu32,
                  dpif_name(dpif_), reply.port_no, upcall_pid);
-    } else if (error == EBUSY && *port_nop != UINT32_MAX) {
-        VLOG_INFO("%s: requested port %"PRIu32" is in use",
-                  dpif_name(dpif_), *port_nop);
+    } else {
+        if (error == EBUSY && *port_nop != UINT32_MAX) {
+            VLOG_INFO("%s: requested port %"PRIu32" is in use",
+                      dpif_name(dpif_), *port_nop);
+        }
         nl_sock_destroy(sock);
         ofpbuf_delete(buf);
         return error;
@@ -958,7 +959,7 @@ dpif_linux_operate__(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
     struct nl_transaction *txnsp[MAX_OPS];
     size_t i;
 
-    assert(n_ops <= MAX_OPS);
+    ovs_assert(n_ops <= MAX_OPS);
     for (i = 0; i < n_ops; i++) {
         struct op_auxdata *aux = &auxes[i];
         struct dpif_op *op = ops[i];
@@ -1579,7 +1580,7 @@ dpif_linux_vport_transact(const struct dpif_linux_vport *request,
     struct ofpbuf *request_buf;
     int error;
 
-    assert((reply != NULL) == (bufp != NULL));
+    ovs_assert((reply != NULL) == (bufp != NULL));
 
     error = dpif_linux_init();
     if (error) {
@@ -1730,7 +1731,7 @@ dpif_linux_dp_transact(const struct dpif_linux_dp *request,
     struct ofpbuf *request_buf;
     int error;
 
-    assert((reply != NULL) == (bufp != NULL));
+    ovs_assert((reply != NULL) == (bufp != NULL));
 
     request_buf = ofpbuf_new(1024);
     dpif_linux_dp_to_ofpbuf(request, request_buf);
@@ -1851,9 +1852,9 @@ dpif_linux_flow_to_ofpbuf(const struct dpif_linux_flow *flow,
     }
 
     /* We never need to send these to the kernel. */
-    assert(!flow->stats);
-    assert(!flow->tcp_flags);
-    assert(!flow->used);
+    ovs_assert(!flow->stats);
+    ovs_assert(!flow->tcp_flags);
+    ovs_assert(!flow->used);
 
     if (flow->clear) {
         nl_msg_put_flag(buf, OVS_FLOW_ATTR_CLEAR);
@@ -1880,7 +1881,7 @@ dpif_linux_flow_transact(struct dpif_linux_flow *request,
     struct ofpbuf *request_buf;
     int error;
 
-    assert((reply != NULL) == (bufp != NULL));
+    ovs_assert((reply != NULL) == (bufp != NULL));
 
     if (reply) {
         request->nlmsg_flags |= NLM_F_ECHO;
index 193ffe4..6e7a5cc 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "dpif.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -160,7 +159,7 @@ static void dp_netdev_execute_actions(struct dp_netdev *,
 static struct dpif_netdev *
 dpif_netdev_cast(const struct dpif *dpif)
 {
-    assert(dpif->dpif_class->open == dpif_netdev_open);
+    ovs_assert(dpif->dpif_class->open == dpif_netdev_open);
     return CONTAINER_OF(dpif, struct dpif_netdev, dpif);
 }
 
@@ -298,7 +297,7 @@ dpif_netdev_open(const struct dpif_class *class, const char *name,
             if (error) {
                 return error;
             }
-            assert(dp != NULL);
+            ovs_assert(dp != NULL);
         }
     } else {
         if (dp->class != class) {
@@ -346,7 +345,7 @@ static void
 dpif_netdev_close(struct dpif *dpif)
 {
     struct dp_netdev *dp = get_dp_netdev(dpif);
-    assert(dp->open_cnt > 0);
+    ovs_assert(dp->open_cnt > 0);
     if (--dp->open_cnt == 0 && dp->destroyed) {
         shash_find_and_delete(&dp_netdevs, dp->name);
         dp_netdev_free(dp);
@@ -1202,7 +1201,7 @@ execute_set_action(struct ofpbuf *packet, const struct nlattr *a)
     case OVS_KEY_ATTR_TUN_ID:
     case OVS_KEY_ATTR_PRIORITY:
     case OVS_KEY_ATTR_SKB_MARK:
-    case OVS_KEY_ATTR_IPV4_TUNNEL:
+    case OVS_KEY_ATTR_TUNNEL:
         /* not implemented */
         break;
 
@@ -1259,7 +1258,6 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
     unsigned int left;
 
     NL_ATTR_FOR_EACH_UNSAFE (a, left, actions, actions_len) {
-        const struct ovs_action_push_vlan *vlan;
         int type = nl_attr_type(a);
 
         switch ((enum ovs_action_attr) type) {
@@ -1271,10 +1269,11 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
             dp_netdev_action_userspace(dp, packet, key, a);
             break;
 
-        case OVS_ACTION_ATTR_PUSH_VLAN:
-            vlan = nl_attr_get(a);
+        case OVS_ACTION_ATTR_PUSH_VLAN: {
+            const struct ovs_action_push_vlan *vlan = nl_attr_get(a);
             eth_push_vlan(packet, vlan->vlan_tci);
             break;
+        }
 
         case OVS_ACTION_ATTR_POP_VLAN:
             eth_pop_vlan(packet);
index 44e946c..4f04c95 100644 (file)
@@ -22,7 +22,6 @@
  * exposed over OpenFlow as a single switch.  Datapaths and the collections of
  * ports that they contain may be fixed or dynamic. */
 
-#include <assert.h>
 #include "openflow/openflow.h"
 #include "dpif.h"
 #include "util.h"
@@ -49,7 +48,7 @@ void dpif_uninit(struct dpif *dpif, bool close);
 static inline void dpif_assert_class(const struct dpif *dpif,
                                      const struct dpif_class *dpif_class)
 {
-    assert(dpif->dpif_class == dpif_class);
+    ovs_assert(dpif->dpif_class == dpif_class);
 }
 
 /* Datapath interface class structure, to be defined by each implementation of
index 18ef790..69d9c34 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "dpif-provider.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <inttypes.h>
@@ -266,7 +265,7 @@ do_open(const char *name, const char *type, bool create, struct dpif **dpifp)
     error = registered_class->dpif_class->open(registered_class->dpif_class,
                                                name, create, &dpif);
     if (!error) {
-        assert(dpif->dpif_class == registered_class->dpif_class);
+        ovs_assert(dpif->dpif_class == registered_class->dpif_class);
         registered_class->refcount++;
     }
 
@@ -330,8 +329,8 @@ dpif_close(struct dpif *dpif)
 
         registered_class = shash_find_data(&dpif_classes,
                 dpif->dpif_class->type);
-        assert(registered_class);
-        assert(registered_class->refcount);
+        ovs_assert(registered_class);
+        ovs_assert(registered_class->refcount);
 
         registered_class->refcount--;
         dpif_uninit(dpif, true);
@@ -615,7 +614,7 @@ dpif_port_get_name(struct dpif *dpif, uint32_t port_no,
     struct dpif_port port;
     int error;
 
-    assert(name_size > 0);
+    ovs_assert(name_size > 0);
 
     error = dpif_port_query_by_number(dpif, port_no, &port);
     if (!error) {
@@ -822,8 +821,8 @@ dpif_flow_put__(struct dpif *dpif, const struct dpif_flow_put *put)
     int error;
 
     COVERAGE_INC(dpif_flow_put);
-    assert(!(put->flags & ~(DPIF_FP_CREATE | DPIF_FP_MODIFY
-                            | DPIF_FP_ZERO_STATS)));
+    ovs_assert(!(put->flags & ~(DPIF_FP_CREATE | DPIF_FP_MODIFY
+                                | DPIF_FP_ZERO_STATS)));
 
     error = dpif->dpif_class->flow_put(dpif, put);
     if (error && put->stats) {
index b648eef..bd1cf45 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "dynamic-string.h"
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -165,7 +164,7 @@ ds_put_format_valist(struct ds *ds, const char *format, va_list args_)
         needed = vsnprintf(&ds->string[ds->length], available, format, args);
         va_end(args);
 
-        assert(needed < available);
+        ovs_assert(needed < available);
         ds->length += needed;
     }
 }
index 7cfbd05..66c0445 100644 (file)
@@ -15,7 +15,6 @@
  */
 #include <config.h>
 #include "fatal-signal.h"
-#include <assert.h>
 #include <errno.h>
 #include <signal.h>
 #include <stdbool.h>
@@ -112,7 +111,7 @@ fatal_signal_add_hook(void (*hook_cb)(void *aux), void (*cancel_cb)(void *aux),
 {
     fatal_signal_init();
 
-    assert(n_hooks < MAX_HOOKS);
+    ovs_assert(n_hooks < MAX_HOOKS);
     hooks[n_hooks].hook_cb = hook_cb;
     hooks[n_hooks].cancel_cb = cancel_cb;
     hooks[n_hooks].aux = aux;
index a13519e..2a3dd3d 100644 (file)
@@ -16,7 +16,6 @@
 #include <config.h>
 #include <sys/types.h>
 #include "flow.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -31,6 +30,7 @@
 #include "csum.h"
 #include "dynamic-string.h"
 #include "hash.h"
+#include "jhash.h"
 #include "match.h"
 #include "ofpbuf.h"
 #include "openflow/openflow.h"
@@ -347,7 +347,7 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t skb_mark,
     memset(flow, 0, sizeof *flow);
 
     if (tnl) {
-        assert(tnl != &flow->tunnel);
+        ovs_assert(tnl != &flow->tunnel);
         flow->tunnel = *tnl;
     }
     flow->in_port = ofp_in_port;
@@ -723,7 +723,7 @@ flow_hash_symmetric_l4(const struct flow *flow, uint32_t basis)
             fields.tp_port = flow->tp_src ^ flow->tp_dst;
         }
     }
-    return hash_bytes(&fields, sizeof fields, basis);
+    return jhash_bytes(&fields, sizeof fields, basis);
 }
 
 /* Hashes the portions of 'flow' designated by 'fields'. */
@@ -734,7 +734,7 @@ flow_hash_fields(const struct flow *flow, enum nx_hash_fields fields,
     switch (fields) {
 
     case NX_HASH_FIELDS_ETH_SRC:
-        return hash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
+        return jhash_bytes(flow->dl_src, sizeof flow->dl_src, basis);
 
     case NX_HASH_FIELDS_SYMMETRIC_L4:
         return flow_hash_symmetric_l4(flow, basis);
@@ -1149,7 +1149,7 @@ miniflow_hash_in_minimask(const struct miniflow *flow,
         }
     }
 
-    return mhash_finish(hash, p - mask->masks.values);
+    return mhash_finish(hash, (p - mask->masks.values) * 4);
 }
 
 /* Returns a hash value for the bits of 'flow' where there are 1-bits in
@@ -1178,7 +1178,7 @@ flow_hash_in_minimask(const struct flow *flow, const struct minimask *mask,
         }
     }
 
-    return mhash_finish(hash, p - mask->masks.values);
+    return mhash_finish(hash, (p - mask->masks.values) * 4);
 }
 \f
 /* Initializes 'dst' as a copy of 'src'.  The caller must eventually free 'dst'
index 41ad1bf..e954d78 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <string.h>
 #include "unaligned.h"
 
-/* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'.
- * 'p' must be properly aligned. */
-uint32_t
-hash_words(const uint32_t *p, size_t n, uint32_t basis)
-{
-    uint32_t a, b, c;
-
-    a = b = c = 0xdeadbeef + (((uint32_t) n) << 2) + basis;
-
-    while (n > 3) {
-        a += p[0];
-        b += p[1];
-        c += p[2];
-        hash_mix(&a, &b, &c);
-        n -= 3;
-        p += 3;
-    }
-
-    switch (n) {
-    case 3:
-        c += p[2];
-        /* fall through */
-    case 2:
-        b += p[1];
-        /* fall through */
-    case 1:
-        a += p[0];
-        hash_final(&a, &b, &c);
-        /* fall through */
-    case 0:
-        break;
-    }
-    return c;
-}
-
 /* Returns the hash of 'a', 'b', and 'c'. */
 uint32_t
 hash_3words(uint32_t a, uint32_t b, uint32_t c)
 {
-    a += 0xdeadbeef;
-    b += 0xdeadbeef;
-    c += 0xdeadbeef;
-    hash_final(&a, &b, &c);
-    return c;
-}
-
-/* Returns the hash of 'a' and 'b'. */
-uint32_t
-hash_2words(uint32_t a, uint32_t b)
-{
-    return hash_3words(a, b, 0);
+    return mhash_finish(mhash_add(mhash_add(mhash_add(a, 0), b), c), 12);
 }
 
 /* Returns the hash of the 'n' bytes at 'p', starting from 'basis'. */
@@ -76,37 +30,30 @@ uint32_t
 hash_bytes(const void *p_, size_t n, uint32_t basis)
 {
     const uint8_t *p = p_;
-    uint32_t a, b, c;
-
-    a = b = c = 0xdeadbeef + n + basis;
+    size_t orig_n = n;
+    uint32_t hash;
 
-    while (n >= 12) {
-        a += get_unaligned_u32((uint32_t *) p);
-        b += get_unaligned_u32((uint32_t *) (p + 4));
-        c += get_unaligned_u32((uint32_t *) (p + 8));
-        hash_mix(&a, &b, &c);
-        n -= 12;
-        p += 12;
+    hash = basis;
+    while (n >= 4) {
+        hash = mhash_add(hash, get_unaligned_u32((const uint32_t *) p));
+        n -= 4;
+        p += 4;
     }
 
     if (n) {
-        uint32_t tmp[3];
+        uint32_t tmp = 0;
 
-        tmp[0] = tmp[1] = tmp[2] = 0;
-        memcpy(tmp, p, n);
-        a += tmp[0];
-        b += tmp[1];
-        c += tmp[2];
-        hash_final(&a, &b, &c);
+        memcpy(&tmp, p, n);
+        hash = mhash_add__(hash, tmp);
     }
 
-    return c;
+    return mhash_finish(hash, orig_n);
 }
 
 /* Returns the hash of the 'n' 32-bit words at 'p', starting from 'basis'.
  * 'p' must be properly aligned. */
 uint32_t
-mhash_words(const uint32_t p[], size_t n_words, uint32_t basis)
+hash_words(const uint32_t p[], size_t n_words, uint32_t basis)
 {
     uint32_t hash;
     size_t i;
@@ -115,5 +62,15 @@ mhash_words(const uint32_t p[], size_t n_words, uint32_t basis)
     for (i = 0; i < n_words; i++) {
         hash = mhash_add(hash, p[i]);
     }
-    return mhash_finish(hash, n_words);
+    return mhash_finish(hash, n_words * 4);
+}
+
+uint32_t
+hash_double(double x, uint32_t basis)
+{
+    uint32_t value[2];
+    BUILD_ASSERT_DECL(sizeof x == sizeof value);
+
+    memcpy(value, &x, sizeof value);
+    return hash_3words(value[0], value[1], basis);
 }
index 701e686..f8a72ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 extern "C" {
 #endif
 
-/* This is the public domain lookup3 hash by Bob Jenkins from
- * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */
-
 static inline uint32_t
 hash_rot(uint32_t x, int k)
 {
     return (x << k) | (x >> (32 - k));
 }
 
-static inline void
-hash_mix(uint32_t *a, uint32_t *b, uint32_t *c)
+uint32_t hash_words(const uint32_t data[], size_t n_words, uint32_t basis);
+uint32_t hash_bytes(const void *, size_t n_bytes, uint32_t basis);
+
+static inline uint32_t hash_int(uint32_t x, uint32_t basis);
+static inline uint32_t hash_2words(uint32_t, uint32_t);
+uint32_t hash_3words(uint32_t, uint32_t, uint32_t);
+
+static inline uint32_t hash_boolean(bool x, uint32_t basis);
+uint32_t hash_double(double, uint32_t basis);
+
+static inline uint32_t hash_pointer(const void *, uint32_t basis);
+static inline uint32_t hash_string(const char *, uint32_t basis);
+
+/* Murmurhash by Austin Appleby,
+ * from http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp.
+ *
+ * The upstream license there says:
+ *
+ * // MurmurHash3 was written by Austin Appleby, and is placed in the public
+ * // domain. The author hereby disclaims copyright to this source code.
+ *
+ * See hash_words() for sample usage. */
+
+static inline uint32_t mhash_add__(uint32_t hash, uint32_t data)
 {
-      *a -= *c; *a ^= hash_rot(*c,  4); *c += *b;
-      *b -= *a; *b ^= hash_rot(*a,  6); *a += *c;
-      *c -= *b; *c ^= hash_rot(*b,  8); *b += *a;
-      *a -= *c; *a ^= hash_rot(*c, 16); *c += *b;
-      *b -= *a; *b ^= hash_rot(*a, 19); *a += *c;
-      *c -= *b; *c ^= hash_rot(*b,  4); *b += *a;
+    data *= 0xcc9e2d51;
+    data = hash_rot(data, 15);
+    data *= 0x1b873593;
+    return hash ^ data;
 }
 
-static inline void
-hash_final(uint32_t *a, uint32_t *b, uint32_t *c)
+static inline uint32_t mhash_add(uint32_t hash, uint32_t data)
 {
-      *c ^= *b; *c -= hash_rot(*b, 14);
-      *a ^= *c; *a -= hash_rot(*c, 11);
-      *b ^= *a; *b -= hash_rot(*a, 25);
-      *c ^= *b; *c -= hash_rot(*b, 16);
-      *a ^= *c; *a -= hash_rot(*c,  4);
-      *b ^= *a; *b -= hash_rot(*a, 14);
-      *c ^= *b; *c -= hash_rot(*b, 24);
+    hash = mhash_add__(hash, data);
+    hash = hash_rot(hash, 13);
+    return hash * 5 + 0xe6546b64;
 }
 
-uint32_t hash_words(const uint32_t *, size_t n_word, uint32_t basis);
-uint32_t hash_2words(uint32_t, uint32_t);
-uint32_t hash_3words(uint32_t, uint32_t, uint32_t);
-uint32_t hash_bytes(const void *, size_t n_bytes, uint32_t basis);
+static inline uint32_t mhash_finish(uint32_t hash, size_t n_bytes)
+{
+    hash ^= n_bytes;
+    hash ^= hash >> 16;
+    hash *= 0x85ebca6b;
+    hash ^= hash >> 13;
+    hash *= 0xc2b2ae35;
+    hash ^= hash >> 16;
+    return hash;
+}
 
 static inline uint32_t hash_string(const char *s, uint32_t basis)
 {
     return hash_bytes(s, strlen(s), basis);
 }
 
-/* This is Bob Jenkins' integer hash from
- * http://burtleburtle.net/bob/hash/integer.html, modified for style.
- *
- * This hash is faster than hash_2words(), but it isn't as good when 'basis' is
- * important.  So use this function for speed or hash_2words() for hash
- * quality. */
 static inline uint32_t hash_int(uint32_t x, uint32_t basis)
 {
-    x -= x << 6;
-    x ^= x >> 17;
-    x -= x << 9;
-    x ^= x << 4;
-    x += basis;
-    x -= x << 3;
-    x ^= x << 10;
-    x ^= x >> 15;
-    return x;
+    return hash_2words(x, basis);
 }
 
 /* An attempt at a useful 1-bit hash function.  Has not been analyzed for
@@ -96,15 +100,6 @@ static inline uint32_t hash_boolean(bool x, uint32_t basis)
     return (x ? P0 : P1) ^ hash_rot(basis, 1);
 }
 
-static inline uint32_t hash_double(double x, uint32_t basis)
-{
-    uint32_t value[2];
-    BUILD_ASSERT_DECL(sizeof x == sizeof value);
-
-    memcpy(value, &x, sizeof value);
-    return hash_3words(value[0], value[1], basis);
-}
-
 static inline uint32_t hash_pointer(const void *p, uint32_t basis)
 {
     /* Often pointers are hashed simply by casting to integer type, but that
@@ -118,46 +113,9 @@ static inline uint32_t hash_pointer(const void *p, uint32_t basis)
     return hash_int((uint32_t) (uintptr_t) p, basis);
 }
 
-/* Murmurhash by Austin Appleby,
- * from http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp.
- *
- * The upstream license there says:
- *
- * // MurmurHash3 was written by Austin Appleby, and is placed in the public
- * // domain. The author hereby disclaims copyright to this source code.
- *
- * Murmurhash is faster and higher-quality than the Jenkins lookup3 hash.  When
- * we have a little more familiarity with it, it's probably a good idea to
- * switch all of OVS to it.
- *
- * For now, we have this implementation here for use by code that needs a hash
- * that is convenient for use one word at a time, since the Jenkins lookup3
- * hash works three words at a time.
- *
- * See mhash_words() for sample usage. */
-
-uint32_t mhash_words(const uint32_t data[], size_t n_words, uint32_t basis);
-
-static inline uint32_t mhash_add(uint32_t hash, uint32_t data)
-{
-    data *= 0xcc9e2d51;
-    data = hash_rot(data, 15);
-    data *= 0x1b873593;
-
-    hash ^= data;
-    hash = hash_rot(hash, 13);
-    return hash * 5 + 0xe6546b64;
-}
-
-static inline uint32_t mhash_finish(uint32_t hash, size_t n)
+static inline uint32_t hash_2words(uint32_t x, uint32_t y)
 {
-    hash ^= n * 4;
-    hash ^= hash_rot(hash, 16);
-    hash *= 0x85ebca6b;
-    hash ^= hash_rot(hash, 13);
-    hash *= 0xc2b2ae35;
-    hash ^= hash_rot(hash, 16);
-    return hash;
+    return mhash_finish(mhash_add(mhash_add(x, 0), y), 4);
 }
 
 #ifdef __cplusplus
index 1971029..97c6959 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "hmap.h"
-#include <assert.h>
 #include <stdint.h>
 #include <string.h>
 #include "coverage.h"
@@ -91,8 +90,8 @@ resize(struct hmap *hmap, size_t new_mask)
     struct hmap tmp;
     size_t i;
 
-    assert(!(new_mask & (new_mask + 1)));
-    assert(new_mask != SIZE_MAX);
+    ovs_assert(!(new_mask & (new_mask + 1)));
+    ovs_assert(new_mask != SIZE_MAX);
 
     hmap_init(&tmp);
     if (new_mask) {
index 1c324c4..0440767 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Nicira, Inc.
+ * Copyright (c) 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.
@@ -18,8 +18,6 @@
 
 #include "hmapx.h"
 
-#include <assert.h>
-
 #include "hash.h"
 
 static struct hmapx_node *
@@ -119,7 +117,7 @@ void
 hmapx_add_assert(struct hmapx *map, void *data)
 {
     bool added OVS_UNUSED = hmapx_add(map, data);
-    assert(added);
+    ovs_assert(added);
 }
 
 /* Removes all of the nodes from 'map'. */
@@ -159,7 +157,7 @@ void
 hmapx_find_and_delete_assert(struct hmapx *map, const void *data)
 {
     bool deleted OVS_UNUSED = hmapx_find_and_delete(map, data);
-    assert(deleted);
+    ovs_assert(deleted);
 }
 
 /* Searches for 'data' in 'map'.  Returns its node, if found, otherwise a null
diff --git a/lib/jhash.c b/lib/jhash.c
new file mode 100644 (file)
index 0000000..4ec2871
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2008, 2009, 2010, 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.
+ */
+
+#include <config.h>
+#include "jhash.h"
+#include <string.h>
+#include "unaligned.h"
+
+/* This is the public domain lookup3 hash by Bob Jenkins from
+ * http://burtleburtle.net/bob/c/lookup3.c, modified for style. */
+
+static inline uint32_t
+jhash_rot(uint32_t x, int k)
+{
+    return (x << k) | (x >> (32 - k));
+}
+
+static inline void
+jhash_mix(uint32_t *a, uint32_t *b, uint32_t *c)
+{
+      *a -= *c; *a ^= jhash_rot(*c,  4); *c += *b;
+      *b -= *a; *b ^= jhash_rot(*a,  6); *a += *c;
+      *c -= *b; *c ^= jhash_rot(*b,  8); *b += *a;
+      *a -= *c; *a ^= jhash_rot(*c, 16); *c += *b;
+      *b -= *a; *b ^= jhash_rot(*a, 19); *a += *c;
+      *c -= *b; *c ^= jhash_rot(*b,  4); *b += *a;
+}
+
+static inline void
+jhash_final(uint32_t *a, uint32_t *b, uint32_t *c)
+{
+      *c ^= *b; *c -= jhash_rot(*b, 14);
+      *a ^= *c; *a -= jhash_rot(*c, 11);
+      *b ^= *a; *b -= jhash_rot(*a, 25);
+      *c ^= *b; *c -= jhash_rot(*b, 16);
+      *a ^= *c; *a -= jhash_rot(*c,  4);
+      *b ^= *a; *b -= jhash_rot(*a, 14);
+      *c ^= *b; *c -= jhash_rot(*b, 24);
+}
+
+/* Returns the Jenkins hash of the 'n' 32-bit words at 'p', starting from
+ * 'basis'.  'p' must be properly aligned.
+ *
+ * Use hash_words() instead, unless you're computing a hash function whose
+ * value is exposed "on the wire" so we don't want to change it. */
+uint32_t
+jhash_words(const uint32_t *p, size_t n, uint32_t basis)
+{
+    uint32_t a, b, c;
+
+    a = b = c = 0xdeadbeef + (((uint32_t) n) << 2) + basis;
+
+    while (n > 3) {
+        a += p[0];
+        b += p[1];
+        c += p[2];
+        jhash_mix(&a, &b, &c);
+        n -= 3;
+        p += 3;
+    }
+
+    switch (n) {
+    case 3:
+        c += p[2];
+        /* fall through */
+    case 2:
+        b += p[1];
+        /* fall through */
+    case 1:
+        a += p[0];
+        jhash_final(&a, &b, &c);
+        /* fall through */
+    case 0:
+        break;
+    }
+    return c;
+}
+
+/* Returns the Jenkins hash of the 'n' bytes at 'p', starting from 'basis'.
+ *
+ * Use jhash_bytes() instead, unless you're computing a hash function whose
+ * value is exposed "on the wire" so we don't want to change it. */
+uint32_t
+jhash_bytes(const void *p_, size_t n, uint32_t basis)
+{
+    const uint8_t *p = p_;
+    uint32_t a, b, c;
+
+    a = b = c = 0xdeadbeef + n + basis;
+
+    while (n >= 12) {
+        a += get_unaligned_u32((uint32_t *) p);
+        b += get_unaligned_u32((uint32_t *) (p + 4));
+        c += get_unaligned_u32((uint32_t *) (p + 8));
+        jhash_mix(&a, &b, &c);
+        n -= 12;
+        p += 12;
+    }
+
+    if (n) {
+        uint32_t tmp[3];
+
+        tmp[0] = tmp[1] = tmp[2] = 0;
+        memcpy(tmp, p, n);
+        a += tmp[0];
+        b += tmp[1];
+        c += tmp[2];
+        jhash_final(&a, &b, &c);
+    }
+
+    return c;
+}
diff --git a/lib/jhash.h b/lib/jhash.h
new file mode 100644 (file)
index 0000000..f83b08f
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2008, 2009, 2010, 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.
+ */
+
+#ifndef JHASH_H
+#define JHASH_H 1
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include "util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This is the public domain lookup3 hash by Bob Jenkins from
+ * http://burtleburtle.net/bob/c/lookup3.c, modified for style.
+ *
+ * Use the functions in hash.h instead if you can.  These are here just for
+ * places where we've exposed a hash function "on the wire" and don't want it
+ * to change. */
+
+uint32_t jhash_words(const uint32_t *, size_t n_word, uint32_t basis);
+uint32_t jhash_bytes(const void *, size_t n_bytes, uint32_t basis);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* jhash.h */
index f0b6456..5c96851 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "json.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
@@ -288,42 +287,42 @@ json_object_put_string(struct json *json, const char *name, const char *value)
 const char *
 json_string(const struct json *json)
 {
-    assert(json->type == JSON_STRING);
+    ovs_assert(json->type == JSON_STRING);
     return json->u.string;
 }
 
 struct json_array *
 json_array(const struct json *json)
 {
-    assert(json->type == JSON_ARRAY);
+    ovs_assert(json->type == JSON_ARRAY);
     return CONST_CAST(struct json_array *, &json->u.array);
 }
 
 struct shash *
 json_object(const struct json *json)
 {
-    assert(json->type == JSON_OBJECT);
+    ovs_assert(json->type == JSON_OBJECT);
     return CONST_CAST(struct shash *, json->u.object);
 }
 
 bool
 json_boolean(const struct json *json)
 {
-    assert(json->type == JSON_TRUE || json->type == JSON_FALSE);
+    ovs_assert(json->type == JSON_TRUE || json->type == JSON_FALSE);
     return json->type == JSON_TRUE;
 }
 
 double
 json_real(const struct json *json)
 {
-    assert(json->type == JSON_REAL || json->type == JSON_INTEGER);
+    ovs_assert(json->type == JSON_REAL || json->type == JSON_INTEGER);
     return json->type == JSON_REAL ? json->u.real : json->u.integer;
 }
 
 int64_t
 json_integer(const struct json *json)
 {
-    assert(json->type == JSON_INTEGER);
+    ovs_assert(json->type == JSON_INTEGER);
     return json->u.integer;
 }
 \f
@@ -1130,8 +1129,8 @@ json_parser_finish(struct json_parser *p)
     }
 
     if (!p->error) {
-        assert(p->height == 1);
-        assert(p->stack[0].json != NULL);
+        ovs_assert(p->height == 1);
+        ovs_assert(p->stack[0].json != NULL);
         json = p->stack[--p->height].json;
     } else {
         json = json_string_create_nocopy(p->error);
index b0d8d34..50073b6 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "jsonrpc.h"
 
-#include <assert.h>
 #include <errno.h>
 
 #include "byteq.h"
@@ -83,7 +82,7 @@ jsonrpc_open(struct stream *stream)
 {
     struct jsonrpc *rpc;
 
-    assert(stream != NULL);
+    ovs_assert(stream != NULL);
 
     rpc = xzalloc(sizeof *rpc);
     rpc->name = xstrdup(stream_get_name(stream));
@@ -473,7 +472,7 @@ jsonrpc_received(struct jsonrpc *rpc)
 static void
 jsonrpc_error(struct jsonrpc *rpc, int error)
 {
-    assert(error);
+    ovs_assert(error);
     if (!rpc->status) {
         rpc->status = error;
         jsonrpc_cleanup(rpc);
index 96857ea..8fd9d89 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011 Nicira, Inc.
+/* Copyright (c) 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.
@@ -16,7 +16,6 @@
 #include <config.h>
 #include "lacp.h"
 
-#include <assert.h>
 #include <stdlib.h>
 
 #include "dynamic-string.h"
@@ -223,7 +222,7 @@ lacp_destroy(struct lacp *lacp)
 void
 lacp_configure(struct lacp *lacp, const struct lacp_settings *s)
 {
-    assert(!eth_addr_is_zero(s->id));
+    ovs_assert(!eth_addr_is_zero(s->id));
 
     if (!lacp->name || strcmp(s->name, lacp->name)) {
         free(lacp->name);
index e572a34..4a95dc1 100644 (file)
@@ -409,7 +409,7 @@ send_features_request(struct lswitch *sw)
     struct ofp_switch_config *osc;
     int ofp_version = rconn_get_version(sw->rconn);
 
-    assert(ofp_version > 0 && ofp_version < 0xff);
+    ovs_assert(ofp_version > 0 && ofp_version < 0xff);
 
     /* Send OFPT_FEATURES_REQUEST. */
     b = ofpraw_alloc(OFPRAW_OFPT_FEATURES_REQUEST, ofp_version, 0);
index 804a7e5..fd06b81 100644 (file)
@@ -15,7 +15,6 @@
  */
 #include <config.h>
 #include "list.h"
-#include <assert.h>
 
 /* Initializes 'list' as an empty list. */
 void
@@ -138,7 +137,7 @@ list_front(const struct list *list_)
 {
     struct list *list = CONST_CAST(struct list *, list_);
 
-    assert(!list_is_empty(list));
+    ovs_assert(!list_is_empty(list));
     return list->next;
 }
 
@@ -149,7 +148,7 @@ list_back(const struct list *list_)
 {
     struct list *list = CONST_CAST(struct list *, list_);
 
-    assert(!list_is_empty(list));
+    ovs_assert(!list_is_empty(list));
     return list->prev;
 }
 
index f609d48..052ac48 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "mac-learning.h"
 
-#include <assert.h>
 #include <inttypes.h>
 #include <stdlib.h>
 
@@ -284,7 +283,7 @@ mac_learning_lookup(const struct mac_learning *ml,
     } else {
         struct mac_entry *e = mac_entry_lookup(ml, dst, vlan);
 
-        assert(e == NULL || e->tag != 0);
+        ovs_assert(e == NULL || e->tag != 0);
         if (tag) {
             /* Tag either the learned port or the lack thereof. */
             *tag |= e ? e->tag : make_unknown_mac_tag(ml, dst, vlan);
index 10dbdcb..f1bf63c 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "match.h"
-#include <assert.h>
 #include <stdlib.h>
 #include "byte-order.h"
 #include "dynamic-string.h"
@@ -177,7 +176,7 @@ void
 match_set_reg_masked(struct match *match, unsigned int reg_idx,
                      uint32_t value, uint32_t mask)
 {
-    assert(reg_idx < FLOW_N_REGS);
+    ovs_assert(reg_idx < FLOW_N_REGS);
     flow_wildcards_set_reg_mask(&match->wc, reg_idx, mask);
     match->flow.regs[reg_idx] = value & mask;
 }
index e38e158..87887a8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
 
 #include "meta-flow.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <netinet/icmp6.h>
@@ -543,7 +542,7 @@ const struct mf_field *mf_from_nxm_header__(uint32_t header);
 const struct mf_field *
 mf_from_id(enum mf_field_id id)
 {
-    assert((unsigned int) id < MFF_N_IDS);
+    ovs_assert((unsigned int) id < MFF_N_IDS);
     return &mf_fields[id];
 }
 
@@ -583,7 +582,7 @@ static void
 nxm_init_add_field(const struct mf_field *mf, uint32_t header)
 {
     if (header) {
-        assert(!mf_from_nxm_header__(header));
+        ovs_assert(!mf_from_nxm_header__(header));
         add_nxm_field(header, mf);
         if (mf->maskable != MFM_NONE) {
             add_nxm_field(NXM_MAKE_WILD_HEADER(header), mf);
@@ -1936,7 +1935,7 @@ mf_from_ethernet_string(const struct mf_field *mf, const char *s,
                         uint8_t mac[ETH_ADDR_LEN],
                         uint8_t mask[ETH_ADDR_LEN])
 {
-    assert(mf->n_bytes == ETH_ADDR_LEN);
+    ovs_assert(mf->n_bytes == ETH_ADDR_LEN);
 
     switch (sscanf(s, ETH_ADDR_SCAN_FMT"/"ETH_ADDR_SCAN_FMT,
                    ETH_ADDR_SCAN_ARGS(mac), ETH_ADDR_SCAN_ARGS(mask))){
@@ -1958,7 +1957,7 @@ mf_from_ipv4_string(const struct mf_field *mf, const char *s,
 {
     int prefix;
 
-    assert(mf->n_bytes == sizeof *ip);
+    ovs_assert(mf->n_bytes == sizeof *ip);
 
     if (sscanf(s, IP_SCAN_FMT"/"IP_SCAN_FMT,
                IP_SCAN_ARGS(ip), IP_SCAN_ARGS(mask)) == IP_SCAN_COUNT * 2) {
@@ -1990,7 +1989,7 @@ mf_from_ipv6_string(const struct mf_field *mf, const char *s,
     const char *name, *netmask;
     int retval;
 
-    assert(mf->n_bytes == sizeof *value);
+    ovs_assert(mf->n_bytes == sizeof *value);
 
     name = strtok_r(str, "/", &save_ptr);
     retval = name ? lookup_ipv6(name, value) : EINVAL;
@@ -2028,7 +2027,7 @@ mf_from_ofp_port_string(const struct mf_field *mf, const char *s,
 {
     uint16_t port;
 
-    assert(mf->n_bytes == sizeof(ovs_be16));
+    ovs_assert(mf->n_bytes == sizeof(ovs_be16));
     if (*s == '-') {
         return xasprintf("%s: negative values not supported for %s",
                          s, mf->name);
@@ -2183,7 +2182,7 @@ mf_parse(const struct mf_field *mf, const char *s,
         return mf_from_frag_string(s, &value->u8, &mask->u8);
 
     case MFS_TNL_FLAGS:
-        assert(mf->n_bytes == sizeof(ovs_be16));
+        ovs_assert(mf->n_bytes == sizeof(ovs_be16));
         return mf_from_tun_flags_string(s, &value->be16, &mask->be16);
     }
     NOT_REACHED();
@@ -2215,7 +2214,7 @@ mf_format_integer_string(const struct mf_field *mf, const uint8_t *valuep,
     unsigned long long int integer;
     int i;
 
-    assert(mf->n_bytes <= 8);
+    ovs_assert(mf->n_bytes <= 8);
 
     integer = 0;
     for (i = 0; i < mf->n_bytes; i++) {
index 9094d04..f46eee8 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 
 #include <stdlib.h>
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <sys/types.h>
@@ -50,6 +49,7 @@
 #include "socket-util.h"
 #include "shash.h"
 #include "svec.h"
+#include "util.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(netdev_bsd);
@@ -157,14 +157,15 @@ is_netdev_bsd_class(const struct netdev_class *netdev_class)
 static struct netdev_bsd *
 netdev_bsd_cast(const struct netdev *netdev)
 {
-    assert(is_netdev_bsd_class(netdev_dev_get_class(netdev_get_dev(netdev))));
+    ovs_assert(is_netdev_bsd_class(netdev_dev_get_class(
+                                       netdev_get_dev(netdev))));
     return CONTAINER_OF(netdev, struct netdev_bsd, netdev);
 }
 
 static struct netdev_dev_bsd *
 netdev_dev_bsd_cast(const struct netdev_dev *netdev_dev)
 {
-    assert(is_netdev_bsd_class(netdev_dev_get_class(netdev_dev)));
+    ovs_assert(is_netdev_bsd_class(netdev_dev_get_class(netdev_dev)));
     return CONTAINER_OF(netdev_dev, struct netdev_dev_bsd, netdev_dev);
 }
 
@@ -1255,6 +1256,7 @@ const struct netdev_class netdev_bsd_class = {
     netdev_bsd_destroy,
     NULL, /* get_config */
     NULL, /* set_config */
+    NULL, /* get_tunnel_config */
     netdev_bsd_open_system,
     netdev_bsd_close,
 
@@ -1315,6 +1317,7 @@ const struct netdev_class netdev_tap_class = {
     netdev_bsd_destroy,
     NULL, /* get_config */
     NULL, /* set_config */
+    NULL, /* get_tunnel_config */
     netdev_bsd_open_system,
     netdev_bsd_close,
 
index 4e97f55..ab43772 100644 (file)
@@ -73,7 +73,7 @@ is_dummy_class(const struct netdev_class *class)
 static struct netdev_dev_dummy *
 netdev_dev_dummy_cast(const struct netdev_dev *netdev_dev)
 {
-    assert(is_dummy_class(netdev_dev_get_class(netdev_dev)));
+    ovs_assert(is_dummy_class(netdev_dev_get_class(netdev_dev)));
     return CONTAINER_OF(netdev_dev, struct netdev_dev_dummy, netdev_dev);
 }
 
@@ -81,7 +81,7 @@ static struct netdev_dummy *
 netdev_dummy_cast(const struct netdev *netdev)
 {
     struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
-    assert(is_dummy_class(netdev_dev_get_class(netdev_dev)));
+    ovs_assert(is_dummy_class(netdev_dev_get_class(netdev_dev)));
     return CONTAINER_OF(netdev, struct netdev_dummy, netdev);
 }
 
index e1936fa..433d168 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "netdev-linux.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <arpa/inet.h>
@@ -444,7 +443,7 @@ static struct netdev_dev_linux *
 netdev_dev_linux_cast(const struct netdev_dev *netdev_dev)
 {
     const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev);
-    assert(is_netdev_linux_class(netdev_class));
+    ovs_assert(is_netdev_linux_class(netdev_class));
 
     return CONTAINER_OF(netdev_dev, struct netdev_dev_linux, netdev_dev);
 }
@@ -454,7 +453,7 @@ netdev_linux_cast(const struct netdev *netdev)
 {
     struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
     const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev);
-    assert(is_netdev_linux_class(netdev_class));
+    ovs_assert(is_netdev_linux_class(netdev_class));
 
     return CONTAINER_OF(netdev, struct netdev_linux, netdev);
 }
@@ -583,7 +582,7 @@ static int
 cache_notifier_ref(void)
 {
     if (!cache_notifier_refcount) {
-        assert(!netdev_linux_cache_notifier);
+        ovs_assert(!netdev_linux_cache_notifier);
 
         netdev_linux_cache_notifier =
             rtnetlink_link_notifier_create(netdev_linux_cache_cb, NULL);
@@ -600,9 +599,9 @@ cache_notifier_ref(void)
 static void
 cache_notifier_unref(void)
 {
-    assert(cache_notifier_refcount > 0);
+    ovs_assert(cache_notifier_refcount > 0);
     if (!--cache_notifier_refcount) {
-        assert(netdev_linux_cache_notifier);
+        ovs_assert(netdev_linux_cache_notifier);
         rtnetlink_link_notifier_destroy(netdev_linux_cache_notifier);
         netdev_linux_cache_notifier = NULL;
     }
@@ -1919,11 +1918,11 @@ netdev_linux_set_qos(struct netdev *netdev,
         if (error) {
             return error;
         }
-        assert(netdev_dev->tc == NULL);
+        ovs_assert(netdev_dev->tc == NULL);
 
         /* Install new qdisc. */
         error = new_ops->tc_install(netdev, details);
-        assert((error == 0) == (netdev_dev->tc != NULL));
+        ovs_assert((error == 0) == (netdev_dev->tc != NULL));
 
         return error;
     }
@@ -4145,7 +4144,7 @@ tc_query_qdisc(const struct netdev *netdev)
 
     /* Instantiate it. */
     load_error = ops->tc_load(CONST_CAST(struct netdev *, netdev), qdisc);
-    assert((load_error == 0) == (netdev_dev->tc != NULL));
+    ovs_assert((load_error == 0) == (netdev_dev->tc != NULL));
     ofpbuf_delete(qdisc);
 
     return error ? error : load_error;
index 6644c8d..1442367 100644 (file)
@@ -19,8 +19,6 @@
 
 /* Generic interface to network devices. */
 
-#include <assert.h>
-
 #include "netdev.h"
 #include "list.h"
 #include "shash.h"
@@ -55,7 +53,7 @@ void netdev_dev_get_devices(const struct netdev_class *,
 static inline void netdev_dev_assert_class(const struct netdev_dev *netdev_dev,
                                            const struct netdev_class *class_)
 {
-    assert(netdev_dev->netdev_class == class_);
+    ovs_assert(netdev_dev->netdev_class == class_);
 }
 
 /* A instance of an open network device.
index 3308544..60437b9 100644 (file)
@@ -91,14 +91,14 @@ is_vport_class(const struct netdev_class *class)
 static const struct vport_class *
 vport_class_cast(const struct netdev_class *class)
 {
-    assert(is_vport_class(class));
+    ovs_assert(is_vport_class(class));
     return CONTAINER_OF(class, struct vport_class, netdev_class);
 }
 
 static struct netdev_dev_vport *
 netdev_dev_vport_cast(const struct netdev_dev *netdev_dev)
 {
-    assert(is_vport_class(netdev_dev_get_class(netdev_dev)));
+    ovs_assert(is_vport_class(netdev_dev_get_class(netdev_dev)));
     return CONTAINER_OF(netdev_dev, struct netdev_dev_vport, netdev_dev);
 }
 
index ef1a6b9..3c528a8 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "netdev.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <netinet/in.h>
@@ -230,7 +229,7 @@ netdev_open(const char *name, const char *type, struct netdev **netdevp)
         if (error) {
             return error;
         }
-        assert(netdev_dev->netdev_class == class);
+        ovs_assert(netdev_dev->netdev_class == class);
 
     }
 
@@ -311,7 +310,7 @@ netdev_close(struct netdev *netdev)
     if (netdev) {
         struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
 
-        assert(netdev_dev->ref_cnt);
+        ovs_assert(netdev_dev->ref_cnt);
         netdev_dev->ref_cnt--;
         netdev_uninit(netdev, true);
 
@@ -406,8 +405,8 @@ netdev_recv(struct netdev *netdev, struct ofpbuf *buffer)
     int (*recv)(struct netdev *, void *, size_t);
     int retval;
 
-    assert(buffer->size == 0);
-    assert(ofpbuf_tailroom(buffer) >= ETH_TOTAL_MIN);
+    ovs_assert(buffer->size == 0);
+    ovs_assert(ofpbuf_tailroom(buffer) >= ETH_TOTAL_MIN);
 
     recv = netdev_get_dev(netdev)->netdev_class->recv;
     retval = (recv
@@ -1318,7 +1317,7 @@ void
 netdev_dev_init(struct netdev_dev *netdev_dev, const char *name,
                 const struct netdev_class *netdev_class)
 {
-    assert(!shash_find(&netdev_dev_shash, name));
+    ovs_assert(!shash_find(&netdev_dev_shash, name));
 
     memset(netdev_dev, 0, sizeof *netdev_dev);
     netdev_dev->netdev_class = netdev_class;
@@ -1338,7 +1337,7 @@ netdev_dev_uninit(struct netdev_dev *netdev_dev, bool destroy)
 {
     char *name = netdev_dev->name;
 
-    assert(!netdev_dev->ref_cnt);
+    ovs_assert(!netdev_dev->ref_cnt);
 
     shash_delete(&netdev_dev_shash, netdev_dev->node);
 
index 8f6daff..6739ece 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "netlink-notifier.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <poll.h>
 #include <stdlib.h>
@@ -87,7 +86,7 @@ void
 nln_destroy(struct nln *nln)
 {
     if (nln) {
-        assert(list_is_empty(&nln->all_notifiers));
+        ovs_assert(list_is_empty(&nln->all_notifiers));
         nl_sock_destroy(nln->notify_sock);
         free(nln);
     }
index 49a8493..847f11f 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "netlink-socket.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
@@ -242,7 +241,7 @@ nl_sock_join_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
 int
 nl_sock_leave_mcgroup(struct nl_sock *sock, unsigned int multicast_group)
 {
-    assert(!sock->dump);
+    ovs_assert(!sock->dump);
     if (setsockopt(sock->fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP,
                    &multicast_group, sizeof multicast_group) < 0) {
         VLOG_WARN("could not leave multicast group %u (%s)",
@@ -333,7 +332,7 @@ nl_sock_recv__(struct nl_sock *sock, struct ofpbuf *buf, bool wait)
     struct msghdr msg;
     ssize_t retval;
 
-    assert(buf->allocated >= sizeof *nlmsghdr);
+    ovs_assert(buf->allocated >= sizeof *nlmsghdr);
     ofpbuf_clear(buf);
 
     iov[0].iov_base = buf->base;
@@ -881,7 +880,7 @@ nl_dump_done(struct nl_dump *dump)
     while (!dump->status) {
         struct ofpbuf reply;
         if (!nl_dump_next(dump, &reply)) {
-            assert(dump->status);
+            ovs_assert(dump->status);
         }
     }
 
@@ -1100,7 +1099,7 @@ nl_lookup_genl_family(const char *name, int *number)
         }
         ofpbuf_delete(reply);
 
-        assert(*number != 0);
+        ovs_assert(*number != 0);
     }
     return *number > 0 ? 0 : -*number;
 }
index 5414239..c8e5905 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "netlink.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <sys/types.h>
@@ -113,7 +112,7 @@ nl_msg_put_nlmsghdr(struct ofpbuf *msg,
 {
     struct nlmsghdr *nlmsghdr;
 
-    assert(msg->size == 0);
+    ovs_assert(msg->size == 0);
 
     nl_msg_reserve(msg, NLMSG_HDRLEN + expected_payload);
     nlmsghdr = nl_msg_put_uninit(msg, NLMSG_HDRLEN);
@@ -152,7 +151,7 @@ nl_msg_put_genlmsghdr(struct ofpbuf *msg, size_t expected_payload,
     struct genlmsghdr *genlmsghdr;
 
     nl_msg_put_nlmsghdr(msg, GENL_HDRLEN + expected_payload, family, flags);
-    assert(msg->size == NLMSG_HDRLEN);
+    ovs_assert(msg->size == NLMSG_HDRLEN);
     genlmsghdr = nl_msg_put_uninit(msg, GENL_HDRLEN);
     genlmsghdr->cmd = cmd;
     genlmsghdr->version = version;
@@ -214,7 +213,7 @@ nl_msg_put_unspec_uninit(struct ofpbuf *msg, uint16_t type, size_t size)
 {
     size_t total_size = NLA_HDRLEN + size;
     struct nlattr* nla = nl_msg_put_uninit(msg, total_size);
-    assert(NLA_ALIGN(total_size) <= UINT16_MAX);
+    ovs_assert(NLA_ALIGN(total_size) <= UINT16_MAX);
     nla->nla_len = total_size;
     nla->nla_type = type;
     return nla + 1;
@@ -313,7 +312,7 @@ nl_msg_push_unspec_uninit(struct ofpbuf *msg, uint16_t type, size_t size)
 {
     size_t total_size = NLA_HDRLEN + size;
     struct nlattr* nla = nl_msg_push_uninit(msg, total_size);
-    assert(NLA_ALIGN(total_size) <= UINT16_MAX);
+    ovs_assert(NLA_ALIGN(total_size) <= UINT16_MAX);
     nla->nla_len = total_size;
     nla->nla_type = type;
     return nla + 1;
@@ -474,7 +473,7 @@ nl_attr_type(const struct nlattr *nla)
 const void *
 nl_attr_get(const struct nlattr *nla)
 {
-    assert(nla->nla_len >= NLA_HDRLEN);
+    ovs_assert(nla->nla_len >= NLA_HDRLEN);
     return nla + 1;
 }
 
@@ -482,7 +481,7 @@ nl_attr_get(const struct nlattr *nla)
 size_t
 nl_attr_get_size(const struct nlattr *nla)
 {
-    assert(nla->nla_len >= NLA_HDRLEN);
+    ovs_assert(nla->nla_len >= NLA_HDRLEN);
     return nla->nla_len - NLA_HDRLEN;
 }
 
@@ -491,7 +490,7 @@ nl_attr_get_size(const struct nlattr *nla)
 const void *
 nl_attr_get_unspec(const struct nlattr *nla, size_t size)
 {
-    assert(nla->nla_len >= NLA_HDRLEN + size);
+    ovs_assert(nla->nla_len >= NLA_HDRLEN + size);
     return nla + 1;
 }
 
@@ -577,8 +576,8 @@ nl_attr_get_be64(const struct nlattr *nla)
 const char *
 nl_attr_get_string(const struct nlattr *nla)
 {
-    assert(nla->nla_len > NLA_HDRLEN);
-    assert(memchr(nl_attr_get(nla), '\0', nla->nla_len - NLA_HDRLEN) != NULL);
+    ovs_assert(nla->nla_len > NLA_HDRLEN);
+    ovs_assert(memchr(nl_attr_get(nla), '\0', nla->nla_len - NLA_HDRLEN));
     return nl_attr_get(nla);
 }
 
index ecaab05..4d7fcd6 100644 (file)
@@ -121,7 +121,7 @@ nx_pull_raw(const uint8_t *p, unsigned int match_len, bool strict,
 {
     uint32_t header;
 
-    assert((cookie != NULL) == (cookie_mask != NULL));
+    ovs_assert((cookie != NULL) == (cookie_mask != NULL));
 
     match_init_catchall(match);
     if (cookie) {
@@ -1053,7 +1053,7 @@ set_field_format(const struct ofpact_reg_load *load, struct ds *s)
     const struct mf_field *mf = load->dst.field;
     union mf_value value;
 
-    assert(load->ofpact.compat == OFPUTIL_OFPAT12_SET_FIELD);
+    ovs_assert(load->ofpact.compat == OFPUTIL_OFPAT12_SET_FIELD);
     ds_put_format(s, "set_field:");
     memset(&value, 0, sizeof value);
     bitwise_copy(&load->subvalue, sizeof load->subvalue, 0,
index e2f21da..96a9523 100644 (file)
@@ -95,7 +95,7 @@ ovs_key_attr_to_string(enum ovs_key_attr attr)
     case OVS_KEY_ATTR_PRIORITY: return "skb_priority";
     case OVS_KEY_ATTR_SKB_MARK: return "skb_mark";
     case OVS_KEY_ATTR_TUN_ID: return "tun_id";
-    case OVS_KEY_ATTR_IPV4_TUNNEL: return "ipv4_tunnel";
+    case OVS_KEY_ATTR_TUNNEL: return "tunnel";
     case OVS_KEY_ATTR_IN_PORT: return "in_port";
     case OVS_KEY_ATTR_ETHERNET: return "eth";
     case OVS_KEY_ATTR_VLAN: return "vlan";
@@ -617,7 +617,7 @@ odp_flow_key_attr_len(uint16_t type)
     case OVS_KEY_ATTR_PRIORITY: return 4;
     case OVS_KEY_ATTR_SKB_MARK: return 4;
     case OVS_KEY_ATTR_TUN_ID: return 8;
-    case OVS_KEY_ATTR_IPV4_TUNNEL: return sizeof(struct ovs_key_ipv4_tunnel);
+    case OVS_KEY_ATTR_TUNNEL: return -2;
     case OVS_KEY_ATTR_IN_PORT: return 4;
     case OVS_KEY_ATTR_ETHERNET: return sizeof(struct ovs_key_ethernet);
     case OVS_KEY_ATTR_VLAN: return sizeof(ovs_be16);
@@ -672,19 +672,109 @@ ovs_frag_type_to_string(enum ovs_frag_type type)
     }
 }
 
-static const char *
-odp_tun_flag_to_string(uint32_t flags)
+static int
+tunnel_key_attr_len(int type)
 {
-    switch (flags) {
-    case OVS_TNL_F_DONT_FRAGMENT:
-        return "df";
-    case OVS_TNL_F_CSUM:
-        return "csum";
-    case OVS_TNL_F_KEY:
-        return "key";
-    default:
-        return NULL;
+    switch (type) {
+    case OVS_TUNNEL_KEY_ATTR_ID: return 8;
+    case OVS_TUNNEL_KEY_ATTR_IPV4_SRC: return 4;
+    case OVS_TUNNEL_KEY_ATTR_IPV4_DST: return 4;
+    case OVS_TUNNEL_KEY_ATTR_TOS: return 1;
+    case OVS_TUNNEL_KEY_ATTR_TTL: return 1;
+    case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT: return 0;
+    case OVS_TUNNEL_KEY_ATTR_CSUM: return 0;
+    case __OVS_TUNNEL_KEY_ATTR_MAX:
+        return -1;
     }
+    return -1;
+}
+
+static enum odp_key_fitness
+tun_key_from_attr(const struct nlattr *attr, struct flow_tnl *tun)
+{
+    unsigned int left;
+    const struct nlattr *a;
+    bool ttl = false;
+    bool unknown = false;
+
+    NL_NESTED_FOR_EACH(a, left, attr) {
+        uint16_t type = nl_attr_type(a);
+        size_t len = nl_attr_get_size(a);
+        int expected_len = tunnel_key_attr_len(type);
+
+        if (len != expected_len && expected_len >= 0) {
+            return ODP_FIT_ERROR;
+        }
+
+        switch (type) {
+        case OVS_TUNNEL_KEY_ATTR_ID:
+            tun->tun_id = nl_attr_get_be64(a);
+            tun->flags |= FLOW_TNL_F_KEY;
+            break;
+        case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
+            tun->ip_src = nl_attr_get_be32(a);
+            break;
+        case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
+            tun->ip_dst = nl_attr_get_be32(a);
+            break;
+        case OVS_TUNNEL_KEY_ATTR_TOS:
+            tun->ip_tos = nl_attr_get_u8(a);
+            break;
+        case OVS_TUNNEL_KEY_ATTR_TTL:
+            tun->ip_ttl = nl_attr_get_u8(a);
+            ttl = true;
+            break;
+        case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
+            tun->flags |= FLOW_TNL_F_DONT_FRAGMENT;
+            break;
+        case OVS_TUNNEL_KEY_ATTR_CSUM:
+            tun->flags |= FLOW_TNL_F_CSUM;
+            break;
+        default:
+            /* Allow this to show up as unexpected, if there are unknown
+             * tunnel attribute, eventually resulting in ODP_FIT_TOO_MUCH. */
+            unknown = true;
+            break;
+        }
+    }
+
+    if (!ttl) {
+        return ODP_FIT_ERROR;
+    }
+    if (unknown) {
+            return ODP_FIT_TOO_MUCH;
+    }
+    return ODP_FIT_PERFECT;
+}
+
+static void
+tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key)
+{
+    size_t tun_key_ofs;
+
+    tun_key_ofs = nl_msg_start_nested(a, OVS_KEY_ATTR_TUNNEL);
+
+    if (tun_key->flags & FLOW_TNL_F_KEY) {
+        nl_msg_put_be64(a, OVS_TUNNEL_KEY_ATTR_ID, tun_key->tun_id);
+    }
+    if (tun_key->ip_src) {
+        nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tun_key->ip_src);
+    }
+    if (tun_key->ip_dst) {
+        nl_msg_put_be32(a, OVS_TUNNEL_KEY_ATTR_IPV4_DST, tun_key->ip_dst);
+    }
+    if (tun_key->ip_tos) {
+        nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TOS, tun_key->ip_tos);
+    }
+    nl_msg_put_u8(a, OVS_TUNNEL_KEY_ATTR_TTL, tun_key->ip_ttl);
+    if (tun_key->flags & FLOW_TNL_F_DONT_FRAGMENT) {
+        nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
+    }
+    if (tun_key->flags & FLOW_TNL_F_CSUM) {
+        nl_msg_put_flag(a, OVS_TUNNEL_KEY_ATTR_CSUM);
+    }
+
+    nl_msg_end_nested(a, tun_key_ofs);
 }
 
 static void
@@ -699,7 +789,7 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
     const struct ovs_key_icmpv6 *icmpv6_key;
     const struct ovs_key_arp *arp_key;
     const struct ovs_key_nd *nd_key;
-    const struct ovs_key_ipv4_tunnel *ipv4_tun_key;
+    struct flow_tnl tun_key;
     enum ovs_key_attr attr = nl_attr_type(a);
     int expected_len;
 
@@ -734,18 +824,22 @@ format_odp_key_attr(const struct nlattr *a, struct ds *ds)
         ds_put_format(ds, "(%#"PRIx64")", ntohll(nl_attr_get_be64(a)));
         break;
 
-    case OVS_KEY_ATTR_IPV4_TUNNEL:
-        ipv4_tun_key = nl_attr_get(a);
-        ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
-                      "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
-                      ntohll(ipv4_tun_key->tun_id),
-                      IP_ARGS(ipv4_tun_key->ipv4_src),
-                      IP_ARGS(ipv4_tun_key->ipv4_dst),
-                      ipv4_tun_key->ipv4_tos, ipv4_tun_key->ipv4_ttl);
-
-        format_flags(ds, odp_tun_flag_to_string,
-                     ipv4_tun_key->tun_flags, ',');
-        ds_put_format(ds, "))");
+    case OVS_KEY_ATTR_TUNNEL:
+        memset(&tun_key, 0, sizeof tun_key);
+        if (tun_key_from_attr(a, &tun_key) == ODP_FIT_ERROR) {
+            ds_put_format(ds, "(error)");
+        } else {
+            ds_put_format(ds, "(tun_id=0x%"PRIx64",src="IP_FMT",dst="IP_FMT","
+                          "tos=0x%"PRIx8",ttl=%"PRIu8",flags(",
+                          ntohll(tun_key.tun_id),
+                          IP_ARGS(tun_key.ip_src),
+                          IP_ARGS(tun_key.ip_dst),
+                          tun_key.ip_tos, tun_key.ip_ttl);
+
+            format_flags(ds, flow_tun_flag_to_string,
+                         (uint32_t) tun_key.flags, ',');
+            ds_put_format(ds, "))");
+        }
         break;
 
     case OVS_KEY_ATTR_IN_PORT:
@@ -974,23 +1068,24 @@ parse_odp_key_attr(const char *s, const struct simap *port_names,
     {
         char tun_id_s[32];
         int tos, ttl;
-        struct ovs_key_ipv4_tunnel tun_key;
+        struct flow_tnl tun_key;
         int n = -1;
 
-        if (sscanf(s, "ipv4_tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
+        if (sscanf(s, "tunnel(tun_id=%31[x0123456789abcdefABCDEF],"
                    "src="IP_SCAN_FMT",dst="IP_SCAN_FMT
                    ",tos=%i,ttl=%i,flags%n", tun_id_s,
-                    IP_SCAN_ARGS(&tun_key.ipv4_src),
-                    IP_SCAN_ARGS(&tun_key.ipv4_dst), &tos, &ttl,
+                    IP_SCAN_ARGS(&tun_key.ip_src),
+                    IP_SCAN_ARGS(&tun_key.ip_dst), &tos, &ttl,
                     &n) > 0 && n > 0) {
             int res;
+            uint32_t flags;
 
             tun_key.tun_id = htonll(strtoull(tun_id_s, NULL, 0));
-            tun_key.ipv4_tos = tos;
-            tun_key.ipv4_ttl = ttl;
+            tun_key.ip_tos = tos;
+            tun_key.ip_ttl = ttl;
+            res = parse_flags(&s[n], flow_tun_flag_to_string, &flags);
+            tun_key.flags = (uint16_t) flags;
 
-            res = parse_flags(&s[n], odp_tun_flag_to_string,
-                              &tun_key.tun_flags);
             if (res < 0) {
                 return res;
             }
@@ -999,10 +1094,7 @@ parse_odp_key_attr(const char *s, const struct simap *port_names,
                 return -EINVAL;
             }
             n++;
-
-            memset(&tun_key.pad, 0, sizeof tun_key.pad);
-            nl_msg_put_unspec(key, OVS_KEY_ATTR_IPV4_TUNNEL, &tun_key,
-                              sizeof tun_key);
+            tun_key_to_attr(key, &tun_key);
             return n;
         }
     }
@@ -1342,27 +1434,6 @@ ovs_to_odp_frag(uint8_t nw_frag)
           : OVS_FRAG_TYPE_LATER);
 }
 
-/* The set of kernel flags we understand. Used to detect if ODP_FIT_TOO_MUCH */
-#define OVS_TNL_F_KNOWN_MASK \
-    (OVS_TNL_F_DONT_FRAGMENT | OVS_TNL_F_CSUM | OVS_TNL_F_KEY)
-
-/* These allow the flow/kernel view of the flags to change in future */
-static uint32_t
-flow_to_odp_flags(uint16_t flags)
-{
-    return (flags & FLOW_TNL_F_DONT_FRAGMENT ? OVS_TNL_F_DONT_FRAGMENT : 0)
-        | (flags & FLOW_TNL_F_CSUM ? OVS_TNL_F_CSUM : 0)
-        | (flags & FLOW_TNL_F_KEY ? OVS_TNL_F_KEY : 0);
-}
-
-static uint16_t
-odp_to_flow_flags(uint32_t tun_flags)
-{
-    return (tun_flags & OVS_TNL_F_DONT_FRAGMENT ? FLOW_TNL_F_DONT_FRAGMENT : 0)
-        | (tun_flags & OVS_TNL_F_CSUM ? FLOW_TNL_F_CSUM : 0)
-        | (tun_flags & OVS_TNL_F_KEY ? FLOW_TNL_F_KEY : 0);
-}
-
 /* Appends a representation of 'flow' as OVS_KEY_ATTR_* attributes to 'buf'.
  * 'flow->in_port' is ignored (since it is likely to be an OpenFlow port
  * number rather than a datapath port number).  Instead, if 'odp_in_port'
@@ -1383,18 +1454,7 @@ odp_flow_key_from_flow(struct ofpbuf *buf, const struct flow *flow,
     }
 
     if (flow->tunnel.ip_dst) {
-        struct ovs_key_ipv4_tunnel *ipv4_tun_key;
-
-        ipv4_tun_key = nl_msg_put_unspec_uninit(buf, OVS_KEY_ATTR_IPV4_TUNNEL,
-                                            sizeof *ipv4_tun_key);
-        /* layouts differ, flags has different size */
-        ipv4_tun_key->tun_id = flow->tunnel.tun_id;
-        ipv4_tun_key->tun_flags = flow_to_odp_flags(flow->tunnel.flags);
-        ipv4_tun_key->ipv4_src = flow->tunnel.ip_src;
-        ipv4_tun_key->ipv4_dst = flow->tunnel.ip_dst;
-        ipv4_tun_key->ipv4_tos = flow->tunnel.ip_tos;
-        ipv4_tun_key->ipv4_ttl = flow->tunnel.ip_ttl;
-        memset(ipv4_tun_key->pad, 0, sizeof ipv4_tun_key->pad);
+        tun_key_to_attr(buf, &flow->tunnel);
     } else if (flow->tunnel.tun_id != htonll(0)) {
         nl_msg_put_be64(buf, OVS_KEY_ATTR_TUN_ID, flow->tunnel.tun_id);
     }
@@ -1905,23 +1965,14 @@ odp_flow_key_to_flow(const struct nlattr *key, size_t key_len,
         expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TUN_ID;
     }
 
-    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_IPV4_TUNNEL)) {
-        const struct ovs_key_ipv4_tunnel *ipv4_tun_key;
+    if (present_attrs & (UINT64_C(1) << OVS_KEY_ATTR_TUNNEL)) {
+        enum odp_key_fitness res;
 
-        ipv4_tun_key = nl_attr_get(attrs[OVS_KEY_ATTR_IPV4_TUNNEL]);
-
-        flow->tunnel.tun_id = ipv4_tun_key->tun_id;
-        flow->tunnel.ip_src = ipv4_tun_key->ipv4_src;
-        flow->tunnel.ip_dst = ipv4_tun_key->ipv4_dst;
-        flow->tunnel.flags = odp_to_flow_flags(ipv4_tun_key->tun_flags);
-        flow->tunnel.ip_tos = ipv4_tun_key->ipv4_tos;
-        flow->tunnel.ip_ttl = ipv4_tun_key->ipv4_ttl;
-
-        /* Allow this to show up as unexpected, if there are unknown flags,
-         * eventually resulting in ODP_FIT_TOO_MUCH.
-         * OVS_TNL_F_KNOWN_MASK defined locally above. */
-        if (!(ipv4_tun_key->tun_flags & ~OVS_TNL_F_KNOWN_MASK)) {
-            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_IPV4_TUNNEL;
+        res = tun_key_from_attr(attrs[OVS_KEY_ATTR_TUNNEL], &flow->tunnel);
+        if (res == ODP_FIT_ERROR) {
+            return ODP_FIT_ERROR;
+        } else if (res == ODP_FIT_PERFECT) {
+            expected_attrs |= UINT64_C(1) << OVS_KEY_ATTR_TUNNEL;
         }
     }
 
@@ -2017,18 +2068,11 @@ commit_set_tunnel_action(const struct flow *flow, struct flow *base,
 
     /* A valid IPV4_TUNNEL must have non-zero ip_dst. */
     if (flow->tunnel.ip_dst) {
-        struct ovs_key_ipv4_tunnel ipv4_tun_key;
-
-        ipv4_tun_key.tun_id = base->tunnel.tun_id;
-        ipv4_tun_key.tun_flags = flow_to_odp_flags(base->tunnel.flags);
-        ipv4_tun_key.ipv4_src = base->tunnel.ip_src;
-        ipv4_tun_key.ipv4_dst = base->tunnel.ip_dst;
-        ipv4_tun_key.ipv4_tos = base->tunnel.ip_tos;
-        ipv4_tun_key.ipv4_ttl = base->tunnel.ip_ttl;
-        memset(&ipv4_tun_key.pad, 0, sizeof ipv4_tun_key.pad);
-
-        commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4_TUNNEL,
-                          &ipv4_tun_key, sizeof ipv4_tun_key);
+        size_t offset;
+
+        offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET);
+        tun_key_to_attr(odp_actions, &base->tunnel);
+        nl_msg_end_nested(odp_actions, offset);
     } else {
         commit_set_action(odp_actions, OVS_KEY_ATTR_TUN_ID,
                           &base->tunnel.tun_id, sizeof base->tunnel.tun_id);
index 9d38f33..9d0cc86 100644 (file)
@@ -50,23 +50,30 @@ int odp_actions_from_string(const char *, const struct simap *port_names,
  * The longest nlattr-formatted flow key appended by odp_flow_key_from_flow()
  * would be:
  *
- *                         struct  pad  nl hdr  total
- *                         ------  ---  ------  -----
- *  OVS_KEY_ATTR_PRIORITY      4    --     4      8
- *  OVS_KEY_ATTR_TUN_ID        8    --     4     12
- *  OVS_KEY_ATTR_IPV4_TUNNEL  24    --     4     28
- *  OVS_KEY_ATTR_IN_PORT       4    --     4      8
- *  OVS_KEY_ATTR_SKB_MARK      4    --     4      8
- *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
- *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (outer VLAN ethertype)
- *  OVS_KEY_ATTR_8021Q         4    --     4      8
- *  OVS_KEY_ATTR_ENCAP         0    --     4      4  (VLAN encapsulation)
- *  OVS_KEY_ATTR_ETHERTYPE     2     2     4      8  (inner VLAN ethertype)
- *  OVS_KEY_ATTR_IPV6         40    --     4     44
- *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
- *  OVS_KEY_ATTR_ND           28    --     4     32
- *  -------------------------------------------------
- *  total                                       192
+ *                                     struct  pad  nl hdr  total
+ *                                     ------  ---  ------  -----
+ *  OVS_KEY_ATTR_PRIORITY                4    --     4      8
+ *  OVS_KEY_ATTR_TUN_ID                  8    --     4     12
+ *  OVS_KEY_ATTR_TUNNEL                  0    --     4      4
+ *  - OVS_TUNNEL_KEY_ATTR_ID             8    --     4     12
+ *  - OVS_TUNNEL_KEY_ATTR_IPV4_SRC       4    --     4      8
+ *  - OVS_TUNNEL_KEY_ATTR_IPV4_DST       4    --     4      8
+ *  - OVS_TUNNEL_KEY_ATTR_TOS            1    3      4      8
+ *  - OVS_TUNNEL_KEY_ATTR_TTL            1    3      4      8
+ *  - OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT  0    --     4      4
+ *  - OVS_TUNNEL_KEY_ATTR_CSUM           0    --     4      4
+ *  OVS_KEY_ATTR_IN_PORT                 4    --     4      8
+ *  OVS_KEY_ATTR_SKB_MARK                4    --     4      8
+ *  OVS_KEY_ATTR_ETHERNET               12    --     4     16
+ *  OVS_KEY_ATTR_ETHERTYPE               2     2     4      8  (outer VLAN ethertype)
+ *  OVS_KEY_ATTR_8021Q                   4    --     4      8
+ *  OVS_KEY_ATTR_ENCAP                   0    --     4      4  (VLAN encapsulation)
+ *  OVS_KEY_ATTR_ETHERTYPE               2     2     4      8  (inner VLAN ethertype)
+ *  OVS_KEY_ATTR_IPV6                   40    --     4     44
+ *  OVS_KEY_ATTR_ICMPV6                  2     2     4      8
+ *  OVS_KEY_ATTR_ND                     28    --     4     32
+ *  ----------------------------------------------------------
+ *  total                                                 220
  *
  * We include some slack space in case the calculation isn't quite right or we
  * add another field and forget to adjust this value.
index 1bc8a9c..a439d13 100644 (file)
@@ -27,6 +27,7 @@
 #include "nx-match.h"
 #include "ofp-util.h"
 #include "ofpbuf.h"
+#include "util.h"
 #include "vlog.h"
 
 VLOG_DEFINE_THIS_MODULE(ofp_actions);
@@ -794,7 +795,7 @@ ofpacts_from_openflow11(const union ofp_action *in, size_t n_in,
     static inline const struct STRUCT *                         \
     instruction_get_##ENUM(const struct ofp11_instruction *inst)\
     {                                                           \
-        assert(inst->type == htons(ENUM));                      \
+        ovs_assert(inst->type == htons(ENUM));                  \
         return (struct STRUCT *)inst;                           \
     }                                                           \
                                                                 \
@@ -2131,7 +2132,7 @@ ofpact_init(struct ofpact *ofpact, enum ofpact_type type, size_t len)
 void
 ofpact_update_len(struct ofpbuf *ofpacts, struct ofpact *ofpact)
 {
-    assert(ofpact == ofpacts->l2);
+    ovs_assert(ofpact == ofpacts->l2);
     ofpact->len = (char *) ofpbuf_tail(ofpacts) - (char *) ofpact;
 }
 
index 3989040..e930986 100644 (file)
@@ -530,7 +530,7 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len);
     static inline struct STRUCT *                                       \
     ofpact_get_##ENUM(const struct ofpact *ofpact)                      \
     {                                                                   \
-        assert(ofpact->type == OFPACT_##ENUM);                          \
+        ovs_assert(ofpact->type == OFPACT_##ENUM);                      \
         return (struct STRUCT *) ofpact;                                \
     }                                                                   \
                                                                         \
index 6b3a42c..f2a9e8c 100644 (file)
@@ -110,7 +110,7 @@ ofperr_get_pair__(enum ofperr error, const struct ofperr_domain *domain)
 {
     size_t ofs = error - OFPERR_OFS;
 
-    assert(ofperr_is_valid(error));
+    ovs_assert(ofperr_is_valid(error));
     return &domain->errors[ofs];
 }
 
index d0f5da6..47d7615 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Nicira, Inc.
+ * Copyright (c) 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "ofp-msgs.h"
-#include <assert.h>
 #include "byte-order.h"
 #include "dynamic-string.h"
 #include "hash.h"
@@ -253,7 +252,7 @@ ofphdrs_decode_assert(struct ofphdrs *hdrs,
                       const struct ofp_header *oh, size_t length)
 {
     enum ofperr error = ofphdrs_decode(hdrs, oh, length);
-    assert(!error);
+    ovs_assert(!error);
 }
 
 static bool
@@ -416,7 +415,7 @@ ofpraw_pull_assert(struct ofpbuf *msg)
     enum ofpraw raw;
 
     error = ofpraw_pull(&raw, msg);
-    assert(!error);
+    ovs_assert(!error);
     return raw;
 }
 
@@ -525,10 +524,10 @@ ofpraw_alloc_stats_reply(const struct ofp_header *request,
 
     error = ofpraw_decode_partial(&request_raw, request,
                                   ntohs(request->length));
-    assert(!error);
+    ovs_assert(!error);
 
     reply_raw = ofpraw_stats_request_to_reply(request_raw, request->version);
-    assert(reply_raw);
+    ovs_assert(reply_raw);
 
     return ofpraw_alloc_reply(reply_raw, request, extra_tailroom);
 }
@@ -595,10 +594,10 @@ ofpraw_put_stats_reply(const struct ofp_header *request, struct ofpbuf *buf)
     enum ofpraw raw;
 
     error = ofpraw_decode_partial(&raw, request, ntohs(request->length));
-    assert(!error);
+    ovs_assert(!error);
 
     raw = ofpraw_stats_request_to_reply(raw, request->version);
-    assert(raw);
+    ovs_assert(raw);
 
     ofpraw_put__(raw, request->version, request->xid, 0, buf);
 }
@@ -626,7 +625,7 @@ ofpraw_put__(enum ofpraw raw, uint8_t version, ovs_be32 xid,
     if (hdrs->type == OFPT_VENDOR) {
         struct nicira_header *nh = buf->l2;
 
-        assert(hdrs->vendor == NX_VENDOR_ID);
+        ovs_assert(hdrs->vendor == NX_VENDOR_ID);
         nh->vendor = htonl(hdrs->vendor);
         nh->subtype = htonl(hdrs->subtype);
     } else if (version == OFP10_VERSION
@@ -701,13 +700,13 @@ ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
     hdrs = instance->hdrs;
     switch ((enum ofp_version)hdrs.version) {
     case OFP10_VERSION:
-        assert(hdrs.type == OFPT10_STATS_REQUEST);
+        ovs_assert(hdrs.type == OFPT10_STATS_REQUEST);
         hdrs.type = OFPT10_STATS_REPLY;
         break;
     case OFP11_VERSION:
     case OFP12_VERSION:
     case OFP13_VERSION:
-        assert(hdrs.type == OFPT11_STATS_REQUEST);
+        ovs_assert(hdrs.type == OFPT11_STATS_REQUEST);
         hdrs.type = OFPT11_STATS_REPLY;
         break;
     default:
@@ -715,7 +714,7 @@ ofpraw_stats_request_to_reply(enum ofpraw raw, uint8_t version)
     }
 
     error = ofpraw_from_ofphdrs(&reply_raw, &hdrs);
-    assert(!error);
+    ovs_assert(!error);
 
     return reply_raw;
 }
@@ -866,7 +865,7 @@ ofpmp_postappend(struct list *replies, size_t start_ofs)
 {
     struct ofpbuf *msg = ofpbuf_from_list(list_back(replies));
 
-    assert(start_ofs <= UINT16_MAX);
+    ovs_assert(start_ofs <= UINT16_MAX);
     if (msg->size > UINT16_MAX) {
         size_t len = msg->size - start_ofs;
         memcpy(ofpmp_append(replies, len),
@@ -916,14 +915,14 @@ raw_info_get(enum ofpraw raw)
 {
     ofpmsgs_init();
 
-    assert(raw < ARRAY_SIZE(raw_infos));
+    ovs_assert(raw < ARRAY_SIZE(raw_infos));
     return &raw_infos[raw];
 }
 
 static struct raw_instance *
 raw_instance_get(const struct raw_info *info, uint8_t version)
 {
-    assert(version >= info->min_version && version <= info->max_version);
+    ovs_assert(version >= info->min_version && version <= info->max_version);
     return &info->instances[version - info->min_version];
 }
 
index 9c9aaef..c66cd40 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -807,7 +807,7 @@ ofputil_protocols_to_string(enum ofputil_protocol protocols)
 {
     struct ds s;
 
-    assert(!(protocols & ~OFPUTIL_P_ANY));
+    ovs_assert(!(protocols & ~OFPUTIL_P_ANY));
     if (protocols == 0) {
         return xstrdup("none");
     }
@@ -1367,7 +1367,7 @@ ofputil_encode_set_protocol(enum ofputil_protocol current,
         return ofputil_make_flow_mod_table_id(want_tid);
     }
 
-    assert(current == want);
+    ovs_assert(current == want);
 
     *next = current;
     return NULL;
@@ -1381,7 +1381,7 @@ ofputil_encode_nx_set_flow_format(enum nx_flow_format nxff)
     struct nx_set_flow_format *sff;
     struct ofpbuf *msg;
 
-    assert(ofputil_nx_flow_format_is_valid(nxff));
+    ovs_assert(ofputil_nx_flow_format_is_valid(nxff));
 
     msg = ofpraw_alloc(OFPRAW_NXT_SET_FLOW_FORMAT, OFP10_VERSION, 0);
     sff = ofpbuf_put_zeros(msg, sizeof *sff);
@@ -3226,7 +3226,7 @@ ofputil_decode_port_status(const struct ofp_header *oh,
     ps->reason = ops->reason;
 
     retval = ofputil_pull_phy_port(oh->version, &b, &ps->desc);
-    assert(retval != EOF);
+    ovs_assert(retval != EOF);
     return retval;
 }
 
index f8c4260..77162bf 100644 (file)
@@ -17,7 +17,6 @@
 #ifndef OFP_UTIL_H
 #define OFP_UTIL_H 1
 
-#include <assert.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
index a7d4c73..6484ab3 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "ofpbuf.h"
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include "dynamic-string.h"
@@ -421,7 +420,7 @@ ofpbuf_put_hex(struct ofpbuf *b, const char *s, size_t *n)
 void
 ofpbuf_reserve(struct ofpbuf *b, size_t size)
 {
-    assert(!b->size);
+    ovs_assert(!b->size);
     ofpbuf_prealloc_tailroom(b, size);
     b->data = (char*)b->data + size;
 }
@@ -473,7 +472,7 @@ ofpbuf_at(const struct ofpbuf *b, size_t offset, size_t size)
 void *
 ofpbuf_at_assert(const struct ofpbuf *b, size_t offset, size_t size)
 {
-    assert(offset + size <= b->size);
+    ovs_assert(offset + size <= b->size);
     return ((char *) b->data) + offset;
 }
 
@@ -506,7 +505,7 @@ void *
 ofpbuf_pull(struct ofpbuf *b, size_t size)
 {
     void *data = b->data;
-    assert(b->size >= size);
+    ovs_assert(b->size >= size);
     b->data = (char*)b->data + size;
     b->size -= size;
     return data;
index e357233..0afd03a 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "ovsdb-data.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <float.h>
 #include <inttypes.h>
@@ -108,7 +107,7 @@ ovsdb_atom_default(enum ovsdb_atomic_type type)
         inited = true;
     }
 
-    assert(ovsdb_atomic_type_is_valid(type));
+    ovs_assert(ovsdb_atomic_type_is_valid(type));
     return &default_atoms[type];
 }
 
@@ -290,7 +289,7 @@ static void
 ovsdb_symbol_referenced(struct ovsdb_symbol *symbol,
                         const struct ovsdb_base_type *base)
 {
-    assert(base->type == OVSDB_TYPE_UUID);
+    ovs_assert(base->type == OVSDB_TYPE_UUID);
 
     if (base->u.uuid.refTableName) {
         switch (base->u.uuid.refType) {
@@ -879,7 +878,7 @@ ovsdb_datum_default(const struct ovsdb_type *type)
         int kt = type->key.type;
         int vt = type->value.type;
 
-        assert(ovsdb_type_is_valid(type));
+        ovs_assert(ovsdb_type_is_valid(type));
 
         d = &default_data[kt][vt];
         if (!d->n) {
@@ -1543,7 +1542,7 @@ ovsdb_datum_from_smap(struct ovsdb_datum *datum, struct smap *smap)
                    &datum->keys[i].string, &datum->values[i].string);
         i++;
     }
-    assert(i == datum->n);
+    ovs_assert(i == datum->n);
 
     smap_destroy(smap);
     ovsdb_datum_sort_unique(datum, OVSDB_TYPE_STRING, OVSDB_TYPE_STRING);
@@ -1802,7 +1801,7 @@ ovsdb_datum_union(struct ovsdb_datum *a, const struct ovsdb_datum *b,
         struct ovsdb_error *error;
         a->n = n;
         error = ovsdb_datum_sort(a, type->key.type);
-        assert(!error);
+        ovs_assert(!error);
     }
 }
 
@@ -1814,9 +1813,9 @@ ovsdb_datum_subtract(struct ovsdb_datum *a, const struct ovsdb_type *a_type,
     bool changed = false;
     size_t i;
 
-    assert(a_type->key.type == b_type->key.type);
-    assert(a_type->value.type == b_type->value.type
-           || b_type->value.type == OVSDB_TYPE_VOID);
+    ovs_assert(a_type->key.type == b_type->key.type);
+    ovs_assert(a_type->value.type == b_type->value.type
+               || b_type->value.type == OVSDB_TYPE_VOID);
 
     /* XXX The big-O of this could easily be improved. */
     for (i = 0; i < a->n; ) {
@@ -1863,7 +1862,7 @@ ovsdb_symbol_table_put(struct ovsdb_symbol_table *symtab, const char *name,
 {
     struct ovsdb_symbol *symbol;
 
-    assert(!ovsdb_symbol_table_get(symtab, name));
+    ovs_assert(!ovsdb_symbol_table_get(symtab, name));
     symbol = xmalloc(sizeof *symbol);
     symbol->uuid = *uuid;
     symbol->created = created;
index be4b255..0cb0759 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "ovsdb-idl.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <limits.h>
@@ -216,7 +215,7 @@ ovsdb_idl_destroy(struct ovsdb_idl *idl)
     if (idl) {
         size_t i;
 
-        assert(!idl->txn);
+        ovs_assert(!idl->txn);
         ovsdb_idl_clear(idl);
         jsonrpc_session_close(idl->session);
 
@@ -280,7 +279,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
 {
     int i;
 
-    assert(!idl->txn);
+    ovs_assert(!idl->txn);
     jsonrpc_session_run(idl->session);
     for (i = 0; jsonrpc_session_is_connected(idl->session) && i < 50; i++) {
         struct jsonrpc_msg *msg;
@@ -420,7 +419,7 @@ ovsdb_idl_get_mode(struct ovsdb_idl *idl,
 {
     size_t i;
 
-    assert(!idl->change_seqno);
+    ovs_assert(!idl->change_seqno);
 
     for (i = 0; i < idl->class->n_tables; i++) {
         const struct ovsdb_idl_table *table = &idl->tables[i];
@@ -836,7 +835,7 @@ ovsdb_idl_row_unparse(struct ovsdb_idl_row *row)
 static void
 ovsdb_idl_row_clear_old(struct ovsdb_idl_row *row)
 {
-    assert(row->old == row->new);
+    ovs_assert(row->old == row->new);
     if (!ovsdb_idl_row_is_orphan(row)) {
         const struct ovsdb_idl_table_class *class = row->table->class;
         size_t i;
@@ -951,7 +950,7 @@ ovsdb_idl_insert_row(struct ovsdb_idl_row *row, const struct json *row_json)
     const struct ovsdb_idl_table_class *class = row->table->class;
     size_t i;
 
-    assert(!row->old && !row->new);
+    ovs_assert(!row->old && !row->new);
     row->old = row->new = xmalloc(class->n_columns * sizeof *row->old);
     for (i = 0; i < class->n_columns; i++) {
         ovsdb_datum_init_default(&row->old[i], &class->columns[i].type);
@@ -1132,13 +1131,13 @@ ovsdb_idl_read(const struct ovsdb_idl_row *row,
     const struct ovsdb_idl_table_class *class;
     size_t column_idx;
 
-    assert(!ovsdb_idl_row_is_synthetic(row));
+    ovs_assert(!ovsdb_idl_row_is_synthetic(row));
 
     class = row->table->class;
     column_idx = column - class->columns;
 
-    assert(row->new != NULL);
-    assert(column_idx < class->n_columns);
+    ovs_assert(row->new != NULL);
+    ovs_assert(column_idx < class->n_columns);
 
     if (row->written && bitmap_is_set(row->written, column_idx)) {
         return &row->new[column_idx];
@@ -1162,8 +1161,8 @@ ovsdb_idl_get(const struct ovsdb_idl_row *row,
               enum ovsdb_atomic_type key_type OVS_UNUSED,
               enum ovsdb_atomic_type value_type OVS_UNUSED)
 {
-    assert(column->type.key.type == key_type);
-    assert(column->type.value.type == value_type);
+    ovs_assert(column->type.key.type == key_type);
+    ovs_assert(column->type.value.type == value_type);
 
     return ovsdb_idl_read(row, column);
 }
@@ -1219,7 +1218,7 @@ ovsdb_idl_txn_create(struct ovsdb_idl *idl)
 {
     struct ovsdb_idl_txn *txn;
 
-    assert(!idl->txn);
+    ovs_assert(!idl->txn);
     idl->txn = txn = xmalloc(sizeof *txn);
     txn->request_id = NULL;
     txn->idl = idl;
@@ -1286,9 +1285,9 @@ ovsdb_idl_txn_increment(struct ovsdb_idl_txn *txn,
                         const struct ovsdb_idl_row *row,
                         const struct ovsdb_idl_column *column)
 {
-    assert(!txn->inc_table);
-    assert(column->type.key.type == OVSDB_TYPE_INTEGER);
-    assert(column->type.value.type == OVSDB_TYPE_VOID);
+    ovs_assert(!txn->inc_table);
+    ovs_assert(column->type.key.type == OVSDB_TYPE_INTEGER);
+    ovs_assert(column->type.value.type == OVSDB_TYPE_VOID);
 
     txn->inc_table = row->table->class->name;
     txn->inc_column = column->name;
@@ -1729,7 +1728,7 @@ ovsdb_idl_txn_commit_block(struct ovsdb_idl_txn *txn)
 int64_t
 ovsdb_idl_txn_get_increment_new_value(const struct ovsdb_idl_txn *txn)
 {
-    assert(txn->status == TXN_SUCCESS);
+    ovs_assert(txn->status == TXN_SUCCESS);
     return txn->inc_new_value;
 }
 
@@ -1792,7 +1791,7 @@ ovsdb_idl_txn_get_insert_uuid(const struct ovsdb_idl_txn *txn,
 {
     const struct ovsdb_idl_txn_insert *insert;
 
-    assert(txn->status == TXN_SUCCESS || txn->status == TXN_UNCHANGED);
+    ovs_assert(txn->status == TXN_SUCCESS || txn->status == TXN_UNCHANGED);
     HMAP_FOR_EACH_IN_BUCKET (insert, hmap_node,
                              uuid_hash(uuid), &txn->inserted_rows) {
         if (uuid_equals(uuid, &insert->dummy)) {
@@ -1846,10 +1845,10 @@ ovsdb_idl_txn_write(const struct ovsdb_idl_row *row_,
     column_idx = column - class->columns;
     write_only = row->table->modes[column_idx] == OVSDB_IDL_MONITOR;
 
-    assert(row->new != NULL);
-    assert(column_idx < class->n_columns);
-    assert(row->old == NULL ||
-           row->table->modes[column_idx] & OVSDB_IDL_MONITOR);
+    ovs_assert(row->new != NULL);
+    ovs_assert(column_idx < class->n_columns);
+    ovs_assert(row->old == NULL ||
+               row->table->modes[column_idx] & OVSDB_IDL_MONITOR);
 
     if (row->table->idl->verify_write_only && !write_only) {
         VLOG_ERR("Bug: Attempt to write to a read/write column (%s:%s) when"
@@ -1938,9 +1937,9 @@ ovsdb_idl_txn_verify(const struct ovsdb_idl_row *row_,
     class = row->table->class;
     column_idx = column - class->columns;
 
-    assert(row->new != NULL);
-    assert(row->old == NULL ||
-           row->table->modes[column_idx] & OVSDB_IDL_MONITOR);
+    ovs_assert(row->new != NULL);
+    ovs_assert(row->old == NULL ||
+               row->table->modes[column_idx] & OVSDB_IDL_MONITOR);
     if (!row->old
         || (row->written && bitmap_is_set(row->written, column_idx))) {
         return;
@@ -1972,11 +1971,11 @@ ovsdb_idl_txn_delete(const struct ovsdb_idl_row *row_)
         return;
     }
 
-    assert(row->new != NULL);
+    ovs_assert(row->new != NULL);
     if (!row->old) {
         ovsdb_idl_row_unparse(row);
         ovsdb_idl_row_clear_new(row);
-        assert(!row->prereqs);
+        ovs_assert(!row->prereqs);
         hmap_remove(&row->table->rows, &row->hmap_node);
         hmap_remove(&row->table->idl->txn->txn_rows, &row->txn_node);
         free(row);
@@ -2010,7 +2009,7 @@ ovsdb_idl_txn_insert(struct ovsdb_idl_txn *txn,
     struct ovsdb_idl_row *row = ovsdb_idl_row_create__(class);
 
     if (uuid) {
-        assert(!ovsdb_idl_txn_get_row(txn, uuid));
+        ovs_assert(!ovsdb_idl_txn_get_row(txn, uuid));
         row->uuid = *uuid;
     } else {
         uuid_generate(&row->uuid);
@@ -2244,7 +2243,7 @@ struct ovsdb_idl_txn *
 ovsdb_idl_txn_get(const struct ovsdb_idl_row *row)
 {
     struct ovsdb_idl_txn *txn = row->table->idl->txn;
-    assert(txn != NULL);
+    ovs_assert(txn != NULL);
     return txn;
 }
 
@@ -2264,8 +2263,8 @@ ovsdb_idl_txn_get_idl (struct ovsdb_idl_txn *txn)
 void
 ovsdb_idl_set_lock(struct ovsdb_idl *idl, const char *lock_name)
 {
-    assert(!idl->txn);
-    assert(hmap_is_empty(&idl->outstanding_txns));
+    ovs_assert(!idl->txn);
+    ovs_assert(hmap_is_empty(&idl->outstanding_txns));
 
     if (idl->lock_name && (!lock_name || strcmp(lock_name, idl->lock_name))) {
         /* Release previous lock. */
index 812d1af..73dfcdc 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "packets.h"
-#include <assert.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
index aa63be3..1033ba9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 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.
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "pcap.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <string.h>
@@ -50,7 +49,7 @@ pcap_open(const char *file_name, const char *mode)
 {
     FILE *file;
 
-    assert(!strcmp(mode, "rb") || !strcmp(mode, "wb"));
+    ovs_assert(!strcmp(mode, "rb") || !strcmp(mode, "wb"));
 
     file = fopen(file_name, mode);
     if (file == NULL) {
index 7e328bc..fca1dfa 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "poll-loop.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <poll.h>
@@ -289,7 +288,7 @@ static struct poll_waiter *
 new_waiter(int fd, short int events, const char *where)
 {
     struct poll_waiter *waiter = xzalloc(sizeof *waiter);
-    assert(fd >= 0);
+    ovs_assert(fd >= 0);
     waiter->fd = fd;
     waiter->events = events;
     waiter->where = where;
index 9f5c35f..3fc2e18 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "process.h"
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -159,7 +158,7 @@ process_register(const char *name, pid_t pid)
     struct process *p;
     const char *slash;
 
-    assert(sigchld_is_blocked());
+    ovs_assert(sigchld_is_blocked());
 
     p = xzalloc(sizeof *p);
     p->pid = pid;
@@ -308,7 +307,7 @@ process_exited(struct process *p)
 int
 process_status(const struct process *p)
 {
-    assert(p->exited);
+    ovs_assert(p->exited);
     return p->status;
 }
 
index 3ea65d5..45d428c 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "random.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <sys/time.h>
@@ -59,7 +58,7 @@ random_init(void)
 void
 random_set_seed(uint32_t seed_)
 {
-    assert(seed_);
+    ovs_assert(seed_);
     seed = seed_;
 }
 
index 002f367..67ea86c 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "rconn.h"
-#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
@@ -293,7 +292,7 @@ void
 rconn_connect_unreliably(struct rconn *rc,
                          struct vconn *vconn, const char *name)
 {
-    assert(vconn != NULL);
+    ovs_assert(vconn != NULL);
     rconn_disconnect(rc);
     rconn_set_target__(rc, vconn_get_name(vconn), name);
     rc->reliable = false;
@@ -469,7 +468,7 @@ run_ACTIVE(struct rconn *rc)
                  rc->name, (unsigned int) (time_now() - base));
 
         version = rconn_get_version(rc);
-        assert(version >= 0 && version <= 0xff);
+        ovs_assert(version >= 0 && version <= 0xff);
 
         /* Ordering is important here: rconn_send() can transition to BACKOFF,
          * and we don't want to transition back to IDLE if so, because then we
@@ -864,7 +863,7 @@ void
 rconn_packet_counter_destroy(struct rconn_packet_counter *c)
 {
     if (c) {
-        assert(c->ref_cnt > 0);
+        ovs_assert(c->ref_cnt > 0);
         if (!--c->ref_cnt && !c->n_packets) {
             free(c);
         }
@@ -881,13 +880,13 @@ rconn_packet_counter_inc(struct rconn_packet_counter *c, unsigned int n_bytes)
 void
 rconn_packet_counter_dec(struct rconn_packet_counter *c, unsigned int n_bytes)
 {
-    assert(c->n_packets > 0);
-    assert(c->n_bytes >= n_bytes);
+    ovs_assert(c->n_packets > 0);
+    ovs_assert(c->n_bytes >= n_bytes);
 
     c->n_bytes -= n_bytes;
     c->n_packets--;
     if (!c->n_packets) {
-        assert(!c->n_bytes);
+        ovs_assert(!c->n_bytes);
         if (!c->ref_cnt) {
             free(c);
         }
index 0f1e062..40cc7fc 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "reconnect.h"
 
-#include <assert.h>
 #include <stdlib.h>
 
 #include "poll-loop.h"
@@ -503,7 +502,7 @@ reconnect_transition__(struct reconnect *fsm, long long int now,
 static long long int
 reconnect_deadline__(const struct reconnect *fsm)
 {
-    assert(fsm->state_entered != LLONG_MIN);
+    ovs_assert(fsm->state_entered != LLONG_MIN);
     switch (fsm->state) {
     case S_VOID:
     case S_LISTENING:
index 63a09f2..5bdcfb0 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "route-table.h"
 
-#include <assert.h>
 #include <arpa/inet.h>
 #include <sys/socket.h>
 #include <linux/rtnetlink.h>
@@ -161,8 +160,8 @@ void
 route_table_register(void)
 {
     if (!register_count) {
-        assert(!nln);
-        assert(!route_notifier);
+        ovs_assert(!nln);
+        ovs_assert(!route_notifier);
 
         nln = nln_create(NETLINK_ROUTE, RTNLGRP_IPV4_ROUTE,
                          (nln_parse_func *) route_table_parse, &rtmsg);
index f4287fc..3d1c50b 100644 (file)
@@ -17,7 +17,6 @@
 #ifndef SAT_MATH_H
 #define SAT_MATH_H 1
 
-#include <assert.h>
 #include <limits.h>
 
 /* Saturating addition: overflow yields UINT_MAX. */
index 1cf7d6e..4285c07 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "shash.h"
-#include <assert.h>
 #include "hash.h"
 
 static struct shash_node *shash_find__(const struct shash *,
@@ -145,7 +144,7 @@ void
 shash_add_assert(struct shash *sh, const char *name, const void *data)
 {
     bool added OVS_UNUSED = shash_add_once(sh, name, data);
-    assert(added);
+    ovs_assert(added);
 }
 
 /* Searches for 'name' in 'sh'.  If it does not already exist, adds it along
@@ -242,7 +241,7 @@ void *
 shash_find_and_delete_assert(struct shash *sh, const char *name)
 {
     void *data = shash_find_and_delete(sh, name);
-    assert(data != NULL);
+    ovs_assert(data != NULL);
     return data;
 }
 
@@ -277,7 +276,7 @@ shash_sort(const struct shash *sh)
         SHASH_FOR_EACH (node, sh) {
             nodes[i++] = node;
         }
-        assert(i == n);
+        ovs_assert(i == n);
 
         qsort(nodes, n, sizeof *nodes, compare_nodes_by_name);
 
index 152afcf..06c2e75 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "signals.h"
-#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <signal.h>
@@ -82,7 +81,7 @@ signal_register(int signr)
     s->signr = signr;
 
     /* Set up signal handler. */
-    assert(signr >= 1 && signr < N_SIGNALS);
+    ovs_assert(signr >= 1 && signr < N_SIGNALS);
     memset(&sa, 0, sizeof sa);
     sa.sa_handler = signal_handler;
     sigemptyset(&sa.sa_mask);
index f6804aa..cc8ddb8 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "simap.h"
-#include <assert.h>
 #include "hash.h"
 
 static size_t hash_name(const char *, size_t length);
@@ -196,7 +195,7 @@ simap_sort(const struct simap *simap)
         SIMAP_FOR_EACH (node, simap) {
             nodes[i++] = node;
         }
-        assert(i == n);
+        ovs_assert(i == n);
 
         qsort(nodes, n, sizeof *nodes, compare_nodes_by_name);
 
index b81ac09..54b339f 100644 (file)
@@ -15,8 +15,6 @@
 #include <config.h>
 #include "smap.h"
 
-#include <assert.h>
-
 #include "hash.h"
 #include "json.h"
 
@@ -251,7 +249,7 @@ smap_sort(const struct smap *smap)
         SMAP_FOR_EACH (node, smap) {
             nodes[i++] = node;
         }
-        assert(i == n);
+        ovs_assert(i == n);
 
         qsort(nodes, n, sizeof *nodes, compare_nodes_by_key);
 
index c2f74d0..3e3c67f 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "socket-util.h"
 #include <arpa/inet.h>
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <net/if.h>
@@ -1101,7 +1100,7 @@ send_iovec_and_fds(int sock,
                    const struct iovec *iovs, size_t n_iovs,
                    const int fds[], size_t n_fds)
 {
-    assert(sock >= 0);
+    ovs_assert(sock >= 0);
     if (n_fds > 0) {
         union {
             struct cmsghdr cm;
@@ -1109,8 +1108,8 @@ send_iovec_and_fds(int sock,
         } cmsg;
         struct msghdr msg;
 
-        assert(!iovec_is_empty(iovs, n_iovs));
-        assert(n_fds <= SOUTIL_MAX_FDS);
+        ovs_assert(!iovec_is_empty(iovs, n_iovs));
+        ovs_assert(n_fds <= SOUTIL_MAX_FDS);
 
         memset(&cmsg, 0, sizeof cmsg);
         cmsg.cm.cmsg_len = CMSG_LEN(n_fds * sizeof *fds);
@@ -1285,7 +1284,7 @@ recv_data_and_fds(int sock,
             size_t n_fds = (p->cmsg_len - CMSG_LEN(0)) / sizeof *fds;
             const int *fds_data = (const int *) CMSG_DATA(p);
 
-            assert(n_fds > 0);
+            ovs_assert(n_fds > 0);
             if (n_fds > SOUTIL_MAX_FDS) {
                 VLOG_ERR("%zu fds received but only %d supported",
                          n_fds, SOUTIL_MAX_FDS);
index 04039a7..c5b616f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Nicira, Inc.
+ * Copyright (c) 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.
@@ -18,8 +18,6 @@
 
 #include "sset.h"
 
-#include <assert.h>
-
 #include "hash.h"
 
 static uint32_t
@@ -147,7 +145,7 @@ void
 sset_add_assert(struct sset *set, const char *name)
 {
     bool added OVS_UNUSED = sset_add(set, name);
-    assert(added);
+    ovs_assert(added);
 }
 
 /* Adds a copy of each of the 'n' names in 'names' to 'set'. */
@@ -198,7 +196,7 @@ void
 sset_find_and_delete_assert(struct sset *set, const char *name)
 {
     bool deleted OVS_UNUSED = sset_find_and_delete(set, name);
-    assert(deleted);
+    ovs_assert(deleted);
 }
 
 /* Removes a string from 'set' and returns a copy of it.  The caller must free
index 3d293b6..7bff624 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -23,7 +23,6 @@
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
-#include <assert.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include "byte-order.h"
@@ -481,7 +480,7 @@ stp_check_and_reset_fdb_flush(struct stp *stp)
 struct stp_port *
 stp_get_port(struct stp *stp, int port_no)
 {
-    assert(port_no >= 0 && port_no < ARRAY_SIZE(stp->ports));
+    ovs_assert(port_no >= 0 && port_no < ARRAY_SIZE(stp->ports));
     return &stp->ports[port_no];
 }
 
@@ -669,7 +668,7 @@ int
 stp_port_no(const struct stp_port *p)
 {
     struct stp *stp = p->stp;
-    assert(p >= stp->ports && p < &stp->ports[ARRAY_SIZE(stp->ports)]);
+    ovs_assert(p >= stp->ports && p < &stp->ports[ARRAY_SIZE(stp->ports)]);
     return p - stp->ports;
 }
 
@@ -1228,7 +1227,7 @@ stp_hold_timer_expiry(struct stp_port *p)
 static void
 stp_initialize_port(struct stp_port *p, enum stp_state state)
 {
-    assert(state & (STP_DISABLED | STP_BLOCKING));
+    ovs_assert(state & (STP_DISABLED | STP_BLOCKING));
     stp_become_designated_port(p);
     stp_set_port_state(p, state);
     p->topology_change_ack = false;
index f7e1234..1b16f3e 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "stream-fd.h"
-#include <assert.h>
 #include <errno.h>
 #include <poll.h>
 #include <stdlib.h>
index b39dcf0..1db3735 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 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.
@@ -17,7 +17,6 @@
 #ifndef STREAM_PROVIDER_H
 #define STREAM_PROVIDER_H 1
 
-#include <assert.h>
 #include <sys/types.h>
 #include "stream.h"
 
@@ -46,7 +45,7 @@ void stream_set_local_port(struct stream *, ovs_be16 local_port);
 static inline void stream_assert_class(const struct stream *stream,
                                        const struct stream_class *class)
 {
-    assert(stream->class == class);
+    ovs_assert(stream->class == class);
 }
 
 struct stream_class {
@@ -146,7 +145,7 @@ void pstream_init(struct pstream *, const struct pstream_class *, const char *na
 static inline void pstream_assert_class(const struct pstream *pstream,
                                         const struct pstream_class *class)
 {
-    assert(pstream->class == class);
+    ovs_assert(pstream->class == class);
 }
 
 struct pstream_class {
index 184b3ff..23c5591 100644 (file)
@@ -17,7 +17,6 @@
 #include <config.h>
 #include "stream-ssl.h"
 #include "dhparams.h"
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <inttypes.h>
@@ -599,7 +598,7 @@ ssl_recv(struct stream *stream, void *buffer, size_t n)
     ssize_t ret;
 
     /* Behavior of zero-byte SSL_read is poorly defined. */
-    assert(n > 0);
+    ovs_assert(n > 0);
 
     old_state = SSL_get_state(sslv->ssl);
     ret = SSL_read(sslv->ssl, buffer, n);
@@ -897,7 +896,7 @@ ssl_init(void)
     static int init_status = -1;
     if (init_status < 0) {
         init_status = do_ssl_init();
-        assert(init_status >= 0);
+        ovs_assert(init_status >= 0);
     }
     return init_status;
 }
index 6dee17d..6ed7648 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "stream.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <netdb.h>
index 2ee5731..0c6a8c1 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "stream-provider.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <netinet/in.h>
@@ -74,14 +73,14 @@ check_stream_classes(void)
 
     for (i = 0; i < ARRAY_SIZE(stream_classes); i++) {
         const struct stream_class *class = stream_classes[i];
-        assert(class->name != NULL);
-        assert(class->open != NULL);
+        ovs_assert(class->name != NULL);
+        ovs_assert(class->open != NULL);
         if (class->close || class->recv || class->send || class->run
             || class->run_wait || class->wait) {
-            assert(class->close != NULL);
-            assert(class->recv != NULL);
-            assert(class->send != NULL);
-            assert(class->wait != NULL);
+            ovs_assert(class->close != NULL);
+            ovs_assert(class->recv != NULL);
+            ovs_assert(class->send != NULL);
+            ovs_assert(class->wait != NULL);
         } else {
             /* This class delegates to another one. */
         }
@@ -89,12 +88,12 @@ check_stream_classes(void)
 
     for (i = 0; i < ARRAY_SIZE(pstream_classes); i++) {
         const struct pstream_class *class = pstream_classes[i];
-        assert(class->name != NULL);
-        assert(class->listen != NULL);
+        ovs_assert(class->name != NULL);
+        ovs_assert(class->listen != NULL);
         if (class->close || class->accept || class->wait) {
-            assert(class->close != NULL);
-            assert(class->accept != NULL);
-            assert(class->wait != NULL);
+            ovs_assert(class->close != NULL);
+            ovs_assert(class->accept != NULL);
+            ovs_assert(class->wait != NULL);
         } else {
             /* This class delegates to another one. */
         }
@@ -250,7 +249,7 @@ stream_open_block(int error, struct stream **streamp)
             stream_connect_wait(stream);
             poll_block();
         }
-        assert(error != EINPROGRESS);
+        ovs_assert(error != EINPROGRESS);
     }
 
     if (error) {
@@ -317,7 +316,7 @@ static void
 scs_connecting(struct stream *stream)
 {
     int retval = (stream->class->connect)(stream);
-    assert(retval != EINPROGRESS);
+    ovs_assert(retval != EINPROGRESS);
     if (!retval) {
         stream->state = SCS_CONNECTED;
     } else if (retval != EAGAIN) {
@@ -419,8 +418,8 @@ stream_run_wait(struct stream *stream)
 void
 stream_wait(struct stream *stream, enum stream_wait_type wait)
 {
-    assert(wait == STREAM_CONNECT || wait == STREAM_RECV
-           || wait == STREAM_SEND);
+    ovs_assert(wait == STREAM_CONNECT || wait == STREAM_RECV
+               || wait == STREAM_SEND);
 
     switch (stream->state) {
     case SCS_CONNECTING:
@@ -580,8 +579,8 @@ pstream_accept(struct pstream *pstream, struct stream **new_stream)
     if (retval) {
         *new_stream = NULL;
     } else {
-        assert((*new_stream)->state != SCS_CONNECTING
-               || (*new_stream)->class->connect);
+        ovs_assert((*new_stream)->state != SCS_CONNECTING
+                   || (*new_stream)->class->connect);
     }
     return retval;
 }
@@ -651,7 +650,7 @@ stream_init(struct stream *stream, const struct stream_class *class,
                     : SCS_DISCONNECTED);
     stream->error = connect_status;
     stream->name = xstrdup(name);
-    assert(stream->state != SCS_CONNECTING || class->connect);
+    ovs_assert(stream->state != SCS_CONNECTING || class->connect);
 }
 
 void
index 381ee32..d083ebb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 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.
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "svec.h"
-#include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
@@ -141,7 +140,7 @@ svec_sort_unique(struct svec *svec)
 void
 svec_unique(struct svec *svec)
 {
-    assert(svec_is_sorted(svec));
+    ovs_assert(svec_is_sorted(svec));
     if (svec->n > 1) {
         /* This algorithm is lazy and sub-optimal, but it's "obviously correct"
          * and asymptotically optimal . */
@@ -179,8 +178,8 @@ svec_diff(const struct svec *a, const struct svec *b,
 {
     size_t i, j;
 
-    assert(svec_is_sorted(a));
-    assert(svec_is_sorted(b));
+    ovs_assert(svec_is_sorted(a));
+    ovs_assert(svec_is_sorted(b));
     if (a_only) {
         svec_init(a_only);
     }
@@ -233,7 +232,7 @@ svec_find(const struct svec *svec, const char *name)
 {
     char **p;
 
-    assert(svec_is_sorted(svec));
+    ovs_assert(svec_is_sorted(svec));
     p = bsearch(&name, svec->names, svec->n, sizeof *svec->names,
                 compare_strings);
     return p ? p - svec->names : SIZE_MAX;
@@ -261,7 +260,7 @@ svec_is_unique(const struct svec *svec)
 const char *
 svec_get_duplicate(const struct svec *svec)
 {
-    assert(svec_is_sorted(svec));
+    ovs_assert(svec_is_sorted(svec));
     if (svec->n > 1) {
         size_t i;
         for (i = 1; i < svec->n; i++) {
@@ -375,13 +374,13 @@ svec_join(const struct svec *svec,
 const char *
 svec_back(const struct svec *svec)
 {
-    assert(svec->n);
+    ovs_assert(svec->n);
     return svec->names[svec->n - 1];
 }
 
 void
 svec_pop_back(struct svec *svec)
 {
-    assert(svec->n);
+    ovs_assert(svec->n);
     free(svec->names[--svec->n]);
 }
index f24ddc6..15bcec8 100644 (file)
@@ -18,8 +18,6 @@
 
 #include "table.h"
 
-#include <assert.h>
-
 #include "dynamic-string.h"
 #include "json.h"
 #include "ovsdb-data.h"
@@ -143,7 +141,7 @@ table_add_column(struct table *table, const char *heading, ...)
     struct column *column;
     va_list args;
 
-    assert(!table->n_rows);
+    ovs_assert(!table->n_rows);
     if (table->n_columns >= table->allocated_columns) {
         table->columns = x2nrealloc(table->columns, &table->allocated_columns,
                                     sizeof *table->columns);
@@ -204,8 +202,8 @@ table_add_cell(struct table *table)
 {
     size_t x, y;
 
-    assert(table->n_rows > 0);
-    assert(table->current_column < table->n_columns);
+    ovs_assert(table->n_rows > 0);
+    ovs_assert(table->current_column < table->n_columns);
 
     x = table->current_column++;
     y = table->n_rows - 1;
index 2050de0..9d6b4aa 100644 (file)
--- a/lib/tag.h
+++ b/lib/tag.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 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.
@@ -17,7 +17,6 @@
 #ifndef TAG_H
 #define TAG_H 1
 
-#include <assert.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include "util.h"
index d853989..d91305c 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "timeval.h"
-#include <assert.h>
 #include <errno.h>
 #if HAVE_EXECINFO_H
 #include <execinfo.h>
@@ -731,7 +730,7 @@ backtrace_cb(struct unixctl_conn *conn,
 {
     struct ds ds = DS_EMPTY_INITIALIZER;
 
-    assert(HAVE_EXECINFO_H && CACHE_TIME);
+    ovs_assert(HAVE_EXECINFO_H && CACHE_TIME);
     format_backtraces(&ds, 0);
     unixctl_command_reply(conn, ds_cstr(&ds));
     ds_destroy(&ds);
index 8686de3..e59056e 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "unixctl.h"
-#include <assert.h>
 #include <errno.h>
 #include <unistd.h>
 #include "coverage.h"
@@ -110,7 +109,7 @@ unixctl_command_register(const char *name, const char *usage,
     struct unixctl_command *command;
     struct unixctl_command *lookup = shash_find_data(&commands, name);
 
-    assert(!lookup || lookup->cb == cb);
+    ovs_assert(!lookup || lookup->cb == cb);
 
     if (lookup) {
         return;
@@ -133,7 +132,7 @@ unixctl_command_reply__(struct unixctl_conn *conn,
     struct jsonrpc_msg *reply;
 
     COVERAGE_INC(unixctl_replied);
-    assert(conn->request_id);
+    ovs_assert(conn->request_id);
 
     if (!body) {
         body = "";
index c90d556..83d3ff8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "util.h"
-#include <assert.h>
 #include <errno.h>
 #include <limits.h>
 #include <stdarg.h>
@@ -45,6 +44,30 @@ const char *subprogram_name = "";
 /* --version option output. */
 static char *program_version;
 
+void
+ovs_assert_failure(const char *where, const char *function,
+                   const char *condition)
+{
+    /* Prevent an infinite loop (or stack overflow) in case VLOG_ABORT happens
+     * to trigger an assertion failure of its own. */
+    static int reentry = 0;
+
+    switch (reentry++) {
+    case 0:
+        VLOG_ABORT("%s: assertion %s failed in %s()",
+                   where, condition, function);
+        NOT_REACHED();
+
+    case 1:
+        fprintf(stderr, "%s: assertion %s failed in %s()",
+                where, condition, function);
+        abort();
+
+    default:
+        abort();
+    }
+}
+
 void
 out_of_memory(void)
 {
@@ -756,7 +779,7 @@ english_list_delimiter(size_t index, size_t total)
 int
 log_2_floor(uint32_t n)
 {
-    assert(n);
+    ovs_assert(n);
 
 #if !defined(UINT_MAX) || !defined(UINT32_MAX)
 #error "Someone screwed up the #includes."
index 70f3691..b944ec7 100644 (file)
 #define BUILD_ASSERT_DECL_GCCONLY(EXPR) ((void) 0)
 #endif
 
+/* Like the standard assert macro, except:
+ *
+ *   - Writes the failure message to the log.
+ *
+ *   - Not affected by NDEBUG. */
+#define ovs_assert(CONDITION)                                           \
+    if (!OVS_LIKELY(CONDITION)) {                                       \
+        ovs_assert_failure(SOURCE_LOCATOR, __func__, #CONDITION);       \
+    }
+void ovs_assert_failure(const char *, const char *, const char *) NO_RETURN;
+
 /* Casts 'pointer' to 'type' and issues a compiler warning if the cast changes
  * anything other than an outermost "const" or "volatile" qualifier.
  *
index a26d9c5..f4e9a9e 100644 (file)
@@ -20,8 +20,8 @@
 /* Provider interface to vconns, which provide a virtual connection to an
  * OpenFlow device. */
 
-#include <assert.h>
 #include "vconn.h"
+#include "util.h"
 #include "openflow/openflow-common.h"
 \f
 /* Active virtual connection to an OpenFlow device. */
@@ -53,7 +53,7 @@ void vconn_set_local_port(struct vconn *, ovs_be16 local_port);
 static inline void vconn_assert_class(const struct vconn *vconn,
                                       const struct vconn_class *class)
 {
-    assert(vconn->class == class);
+    ovs_assert(vconn->class == class);
 }
 
 struct vconn_class {
@@ -148,7 +148,7 @@ void pvconn_init(struct pvconn *pvconn, struct pvconn_class *class,
 static inline void pvconn_assert_class(const struct pvconn *pvconn,
                                        const struct pvconn_class *class)
 {
-    assert(pvconn->class == class);
+    ovs_assert(pvconn->class == class);
 }
 
 struct pvconn_class {
index 38ce374..613b92c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 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.
@@ -15,7 +15,6 @@
  */
 
 #include <config.h>
-#include <assert.h>
 #include <errno.h>
 #include <poll.h>
 #include <stdlib.h>
index a3792ec..e0223cd 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include "vconn-provider.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <netinet/in.h>
@@ -97,14 +96,14 @@ check_vconn_classes(void)
 
     for (i = 0; i < ARRAY_SIZE(vconn_classes); i++) {
         struct vconn_class *class = vconn_classes[i];
-        assert(class->name != NULL);
-        assert(class->open != NULL);
+        ovs_assert(class->name != NULL);
+        ovs_assert(class->open != NULL);
         if (class->close || class->recv || class->send
             || class->run || class->run_wait || class->wait) {
-            assert(class->close != NULL);
-            assert(class->recv != NULL);
-            assert(class->send != NULL);
-            assert(class->wait != NULL);
+            ovs_assert(class->close != NULL);
+            ovs_assert(class->recv != NULL);
+            ovs_assert(class->send != NULL);
+            ovs_assert(class->wait != NULL);
         } else {
             /* This class delegates to another one. */
         }
@@ -112,12 +111,12 @@ check_vconn_classes(void)
 
     for (i = 0; i < ARRAY_SIZE(pvconn_classes); i++) {
         struct pvconn_class *class = pvconn_classes[i];
-        assert(class->name != NULL);
-        assert(class->listen != NULL);
+        ovs_assert(class->name != NULL);
+        ovs_assert(class->listen != NULL);
         if (class->close || class->accept || class->wait) {
-            assert(class->close != NULL);
-            assert(class->accept != NULL);
-            assert(class->wait != NULL);
+            ovs_assert(class->close != NULL);
+            ovs_assert(class->accept != NULL);
+            ovs_assert(class->wait != NULL);
         } else {
             /* This class delegates to another one. */
         }
@@ -253,7 +252,7 @@ vconn_open(const char *name, uint32_t allowed_versions, uint8_t dscp,
     }
 
     /* Success. */
-    assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
+    ovs_assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
     *vconnp = vconn;
     return 0;
 
@@ -399,7 +398,7 @@ static void
 vcs_connecting(struct vconn *vconn)
 {
     int retval = (vconn->class->connect)(vconn);
-    assert(retval != EINPROGRESS);
+    ovs_assert(retval != EINPROGRESS);
     if (!retval) {
         vconn->state = VCS_SEND_HELLO;
     } else if (retval != EAGAIN) {
@@ -664,7 +663,7 @@ do_send(struct vconn *vconn, struct ofpbuf *msg)
 {
     int retval;
 
-    assert(msg->size >= sizeof(struct ofp_header));
+    ovs_assert(msg->size >= sizeof(struct ofp_header));
 
     ofpmsg_update_length(msg);
     if (!VLOG_IS_DBG_ENABLED()) {
@@ -695,7 +694,7 @@ vconn_connect_block(struct vconn *vconn)
         vconn_connect_wait(vconn);
         poll_block();
     }
-    assert(error != EINPROGRESS);
+    ovs_assert(error != EINPROGRESS);
 
     return error;
 }
@@ -892,7 +891,7 @@ vconn_transact_multiple_noreply(struct vconn *vconn, struct list *requests,
 void
 vconn_wait(struct vconn *vconn, enum vconn_wait_type wait)
 {
-    assert(wait == WAIT_CONNECT || wait == WAIT_RECV || wait == WAIT_SEND);
+    ovs_assert(wait == WAIT_CONNECT || wait == WAIT_RECV || wait == WAIT_SEND);
 
     switch (vconn->state) {
     case VCS_CONNECTING:
@@ -1059,8 +1058,8 @@ pvconn_accept(struct pvconn *pvconn, struct vconn **new_vconn)
     if (retval) {
         *new_vconn = NULL;
     } else {
-        assert((*new_vconn)->state != VCS_CONNECTING
-               || (*new_vconn)->class->connect);
+        ovs_assert((*new_vconn)->state != VCS_CONNECTING
+                   || (*new_vconn)->class->connect);
     }
     return retval;
 }
@@ -1104,7 +1103,7 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status,
     vconn->local_ip = 0;
     vconn->local_port = 0;
     vconn->name = xstrdup(name);
-    assert(vconn->state != VCS_CONNECTING || class->connect);
+    ovs_assert(vconn->state != VCS_CONNECTING || class->connect);
 }
 
 void
index 2587cde..7867b07 100644 (file)
@@ -43,6 +43,11 @@ VLOG_DEFINE_THIS_MODULE(vlog);
 
 COVERAGE_DEFINE(vlog_recursive);
 
+/* ovs_assert() logs the assertion message, so using ovs_assert() in this
+ * source file could cause recursion. */
+#undef ovs_assert
+#define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
+
 /* Name for each logging level. */
 static const char *level_names[VLL_N_LEVELS] = {
 #define VLOG_LEVEL(NAME, SYSLOG_LEVEL) #NAME,
index b6d268d..6ca05cd 100644 (file)
 
 VLOG_DEFINE_THIS_MODULE(worker);
 
+/* ovs_assert() logs the assertion message and logging sometimes goes through a
+ * worker, so using ovs_assert() in this source file could cause recursion. */
+#undef ovs_assert
+#define ovs_assert use_assert_instead_of_ovs_assert_in_this_module
+
 /* Header for an RPC request. */
 struct worker_request {
     size_t request_len;              /* Length of the payload in bytes. */
index 56971ce..b94c337 100644 (file)
@@ -1290,8 +1290,8 @@ ofconn_receives_async_msg(const struct ofconn *ofconn,
 {
     const uint32_t *async_config;
 
-    assert(reason < 32);
-    assert((unsigned int) type < OAM_N_TYPES);
+    ovs_assert(reason < 32);
+    ovs_assert((unsigned int) type < OAM_N_TYPES);
 
     if (ofconn_get_protocol(ofconn) == OFPUTIL_P_NONE
         || !rconn_is_connected(ofconn->rconn)) {
index a2ada30..75379d1 100644 (file)
@@ -18,7 +18,6 @@
 
 #include "ofproto-dpif-governor.h"
 
-#include <assert.h>
 #include <stdlib.h>
 
 #include "coverage.h"
@@ -121,7 +120,7 @@ governor_should_install_flow(struct governor *g, uint32_t hash, int n)
     bool install_flow;
     uint8_t *e;
 
-    assert(n > 0);
+    ovs_assert(n > 0);
 
     /* Count these packets and begin a new generation if necessary. */
     g->n_packets += n;
@@ -177,8 +176,8 @@ governor_should_install_flow(struct governor *g, uint32_t hash, int n)
 static void
 governor_new_generation(struct governor *g, unsigned int size)
 {
-    assert(size >= MIN_SIZE && size <= MAX_SIZE);
-    assert(is_pow2(size));
+    ovs_assert(size >= MIN_SIZE && size <= MAX_SIZE);
+    ovs_assert(is_pow2(size));
 
     /* Allocate new table, if necessary. */
     if (g->size != size) {
index 55b4e48..2c216fe 100644 (file)
@@ -565,7 +565,7 @@ static uint16_t odp_port_to_ofp_port(const struct ofproto_dpif *,
 static struct ofport_dpif *
 ofport_dpif_cast(const struct ofport *ofport)
 {
-    assert(ofport->ofproto->ofproto_class == &ofproto_dpif_class);
+    ovs_assert(ofport->ofproto->ofproto_class == &ofproto_dpif_class);
     return ofport ? CONTAINER_OF(ofport, struct ofport_dpif, up) : NULL;
 }
 
@@ -691,7 +691,7 @@ static void ofproto_dpif_unixctl_init(void);
 static struct ofproto_dpif *
 ofproto_dpif_cast(const struct ofproto *ofproto)
 {
-    assert(ofproto->ofproto_class == &ofproto_dpif_class);
+    ovs_assert(ofproto->ofproto_class == &ofproto_dpif_class);
     return CONTAINER_OF(ofproto, struct ofproto_dpif, up);
 }
 
@@ -950,7 +950,7 @@ close_dpif_backer(struct dpif_backer *backer)
 {
     struct shash_node *node;
 
-    assert(backer->refcount > 0);
+    ovs_assert(backer->refcount > 0);
 
     if (--backer->refcount) {
         return;
@@ -1022,6 +1022,7 @@ open_dpif_backer(const char *type, struct dpif_backer **backerp)
     if (error) {
         VLOG_ERR("failed to open datapath of type %s: %s", type,
                  strerror(error));
+        free(backer);
         return error;
     }
 
@@ -1181,7 +1182,7 @@ add_internal_flow(struct ofproto_dpif *ofproto, int id,
     }
 
     *rulep = rule_dpif_lookup__(ofproto, &fm.match.flow, TBL_INTERNAL);
-    assert(*rulep != NULL);
+    ovs_assert(*rulep != NULL);
 
     return 0;
 }
@@ -2227,8 +2228,8 @@ bundle_set(struct ofproto *ofproto_, void *aux,
         return 0;
     }
 
-    assert(s->n_slaves == 1 || s->bond != NULL);
-    assert((s->lacp != NULL) == (s->lacp_slaves != NULL));
+    ovs_assert(s->n_slaves == 1 || s->bond != NULL);
+    ovs_assert((s->lacp != NULL) == (s->lacp_slaves != NULL));
 
     bundle = bundle_lookup(ofproto, aux);
     if (!bundle) {
@@ -2295,7 +2296,7 @@ bundle_set(struct ofproto *ofproto_, void *aux,
         found: ;
         }
     }
-    assert(list_size(&bundle->ports) <= s->n_slaves);
+    ovs_assert(list_size(&bundle->ports) <= s->n_slaves);
 
     if (list_is_empty(&bundle->ports)) {
         bundle_destroy(bundle);
@@ -3564,7 +3565,7 @@ handle_miss_upcalls(struct dpif_backer *backer, struct dpif_upcall *upcalls,
     HMAP_FOR_EACH (miss, hmap_node, &todo) {
         handle_flow_miss(miss, flow_miss_ops, &n_ops);
     }
-    assert(n_ops <= ARRAY_SIZE(flow_miss_ops));
+    ovs_assert(n_ops <= ARRAY_SIZE(flow_miss_ops));
 
     /* Execute batch. */
     for (i = 0; i < n_ops; i++) {
@@ -3660,7 +3661,7 @@ handle_upcalls(struct dpif_backer *backer, unsigned int max_batch)
     int n_misses;
     int i;
 
-    assert(max_batch <= FLOW_MISS_MAX_BATCH);
+    ovs_assert(max_batch <= FLOW_MISS_MAX_BATCH);
 
     n_misses = 0;
     for (n_processed = 0; n_processed < max_batch; n_processed++) {
@@ -4125,7 +4126,7 @@ facet_remove(struct facet *facet)
     struct ofproto_dpif *ofproto = ofproto_dpif_cast(facet->rule->up.ofproto);
     struct subfacet *subfacet, *next_subfacet;
 
-    assert(!list_is_empty(&facet->subfacets));
+    ovs_assert(!list_is_empty(&facet->subfacets));
 
     /* First uninstall all of the subfacets to get final statistics. */
     LIST_FOR_EACH (subfacet, list_node, &facet->subfacets) {
@@ -4255,8 +4256,8 @@ facet_flush_stats(struct facet *facet)
     struct subfacet *subfacet;
 
     LIST_FOR_EACH (subfacet, list_node, &facet->subfacets) {
-        assert(!subfacet->dp_byte_count);
-        assert(!subfacet->dp_packet_count);
+        ovs_assert(!subfacet->dp_byte_count);
+        ovs_assert(!subfacet->dp_packet_count);
     }
 
     facet_push_stats(facet);
@@ -4613,9 +4614,9 @@ facet_push_stats(struct facet *facet)
 {
     struct dpif_flow_stats stats;
 
-    assert(facet->packet_count >= facet->prev_packet_count);
-    assert(facet->byte_count >= facet->prev_byte_count);
-    assert(facet->used >= facet->prev_used);
+    ovs_assert(facet->packet_count >= facet->prev_packet_count);
+    ovs_assert(facet->byte_count >= facet->prev_byte_count);
+    ovs_assert(facet->used >= facet->prev_used);
 
     stats.n_packets = facet->packet_count - facet->prev_packet_count;
     stats.n_bytes = facet->byte_count - facet->prev_byte_count;
@@ -4932,8 +4933,8 @@ subfacet_uninstall(struct subfacet *subfacet)
         }
         subfacet->path = SF_NOT_INSTALLED;
     } else {
-        assert(subfacet->dp_packet_count == 0);
-        assert(subfacet->dp_byte_count == 0);
+        ovs_assert(subfacet->dp_packet_count == 0);
+        ovs_assert(subfacet->dp_byte_count == 0);
     }
 }
 
@@ -5386,7 +5387,7 @@ fix_sflow_action(struct action_xlate_ctx *ctx)
 
     cookie = ofpbuf_at(ctx->odp_actions, ctx->user_cookie_offset,
                        sizeof(*cookie));
-    assert(cookie->type == USER_ACTION_COOKIE_SFLOW);
+    ovs_assert(cookie->type == USER_ACTION_COOKIE_SFLOW);
 
     compose_sflow_cookie(ctx->ofproto, base->vlan_tci,
                          ctx->sflow_odp_port, ctx->sflow_n_outputs, cookie);
@@ -5580,8 +5581,8 @@ execute_controller_action(struct action_xlate_ctx *ctx, int len,
         /* If the Ethernet type is less than ETH_TYPE_MIN, it's likely an 802.2
          * LLC frame.  Calculating the Ethernet type of these frames is more
          * trouble than seems appropriate for a simple assertion. */
-        assert(ntohs(eh->eth_type) < ETH_TYPE_MIN
-               || eh->eth_type == ctx->flow.dl_type);
+        ovs_assert(ntohs(eh->eth_type) < ETH_TYPE_MIN
+                   || eh->eth_type == ctx->flow.dl_type);
 
         memcpy(eh->eth_src, ctx->flow.dl_src, sizeof eh->eth_src);
         memcpy(eh->eth_dst, ctx->flow.dl_dst, sizeof eh->eth_dst);
@@ -6069,7 +6070,7 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len,
             /* XXX remove recursion */
             /* It is assumed that goto-table is last action */
             struct ofpact_goto_table *ogt = ofpact_get_GOTO_TABLE(a);
-            assert(ctx->table_id < ogt->table_id);
+            ovs_assert(ctx->table_id < ogt->table_id);
             xlate_table_action(ctx, ctx->flow.in_port, ogt->table_id, true);
             break;
         }
index 8e2ea6b..9bae971 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  * Copyright (c) 2010 Jean Tourrilhes - HP-Labs.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -446,12 +446,12 @@ ofproto_create(const char *datapath_name, const char *datapath_type,
     bitmap_set1(ofproto->ofp_port_ids, 0);
 
     /* Check that hidden tables, if any, are at the end. */
-    assert(ofproto->n_tables);
+    ovs_assert(ofproto->n_tables);
     for (i = 0; i + 1 < ofproto->n_tables; i++) {
         enum oftable_flags flags = ofproto->tables[i].flags;
         enum oftable_flags next_flags = ofproto->tables[i + 1].flags;
 
-        assert(!(flags & OFTABLE_HIDDEN) || next_flags & OFTABLE_HIDDEN);
+        ovs_assert(!(flags & OFTABLE_HIDDEN) || next_flags & OFTABLE_HIDDEN);
     }
 
     ofproto->datapath_id = pick_datapath_id(ofproto);
@@ -469,8 +469,8 @@ ofproto_init_tables(struct ofproto *ofproto, int n_tables)
 {
     struct oftable *table;
 
-    assert(!ofproto->n_tables);
-    assert(n_tables >= 1 && n_tables <= 255);
+    ovs_assert(!ofproto->n_tables);
+    ovs_assert(n_tables >= 1 && n_tables <= 255);
 
     ofproto->n_tables = n_tables;
     ofproto->tables = xmalloc(n_tables * sizeof *ofproto->tables);
@@ -493,7 +493,7 @@ ofproto_init_tables(struct ofproto *ofproto, int n_tables)
 void
 ofproto_init_max_ports(struct ofproto *ofproto, uint16_t max_ports)
 {
-    assert(max_ports <= OFPP_MAX);
+    ovs_assert(max_ports <= OFPP_MAX);
     ofproto->max_ports = max_ports;
 }
 
@@ -910,7 +910,7 @@ ofproto_configure_table(struct ofproto *ofproto, int table_id,
 {
     struct oftable *table;
 
-    assert(table_id >= 0 && table_id < ofproto->n_tables);
+    ovs_assert(table_id >= 0 && table_id < ofproto->n_tables);
     table = &ofproto->tables[table_id];
 
     oftable_set_name(table, s->name);
@@ -992,8 +992,8 @@ ofproto_destroy__(struct ofproto *ofproto)
 {
     struct oftable *table;
 
-    assert(list_is_empty(&ofproto->pending));
-    assert(!ofproto->n_pending);
+    ovs_assert(list_is_empty(&ofproto->pending));
+    ovs_assert(!ofproto->n_pending);
 
     connmgr_destroy(ofproto->connmgr);
 
@@ -2072,7 +2072,7 @@ ofproto_rule_destroy__(struct rule *rule)
 void
 ofproto_rule_destroy(struct rule *rule)
 {
-    assert(!rule->pending);
+    ovs_assert(!rule->pending);
     oftable_remove_rule(rule);
     ofproto_rule_destroy__(rule);
 }
@@ -2122,7 +2122,7 @@ rule_execute(struct rule *rule, uint16_t in_port, struct ofpbuf *packet)
 {
     struct flow flow;
 
-    assert(ofpbuf_headroom(packet) >= sizeof(struct ofp10_packet_in));
+    ovs_assert(ofpbuf_headroom(packet) >= sizeof(struct ofp10_packet_in));
 
     flow_extract(packet, 0, 0, NULL, in_port, &flow);
     return rule->ofproto->ofproto_class->rule_execute(rule, &flow, packet);
@@ -2171,7 +2171,7 @@ handle_features_request(struct ofconn *ofconn, const struct ofp_header *oh)
 
     ofproto->ofproto_class->get_features(ofproto, &arp_match_ip,
                                          &features.actions);
-    assert(features.actions & OFPUTIL_A_OUTPUT); /* sanity check */
+    ovs_assert(features.actions & OFPUTIL_A_OUTPUT); /* sanity check */
 
     /* Count only non-hidden tables in the number of tables.  (Hidden tables,
      * if present, are always at the end.) */
@@ -2239,7 +2239,7 @@ handle_set_config(struct ofconn *ofconn, const struct ofp_header *oh)
         enum ofp_config_flags cur = ofproto->frag_handling;
         enum ofp_config_flags next = flags & OFPC_FRAG_MASK;
 
-        assert((cur & OFPC_FRAG_MASK) == cur);
+        ovs_assert((cur & OFPC_FRAG_MASK) == cur);
         if (cur != next) {
             if (ofproto->ofproto_class->set_frag_handling(ofproto, next)) {
                 ofproto->frag_handling = next;
@@ -2809,11 +2809,7 @@ flow_stats_ds(struct rule *rule, struct ds *results)
     ds_put_format(results, "n_bytes=%"PRIu64", ", byte_count);
     cls_rule_format(&rule->cr, results);
     ds_put_char(results, ',');
-    if (rule->ofpacts_len > 0) {
-        ofpacts_format(rule->ofpacts, rule->ofpacts_len, results);
-    } else {
-        ds_put_cstr(results, "drop");
-    }
+    ofpacts_format(rule->ofpacts, rule->ofpacts_len, results);
     ds_put_cstr(results, "\n");
 }
 
@@ -3111,7 +3107,7 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn,
             if (error) {
                 return error;
             }
-            assert(table_id < ofproto->n_tables);
+            ovs_assert(table_id < ofproto->n_tables);
             table = &ofproto->tables[table_id];
         } else {
             table = &ofproto->tables[0];
@@ -3469,7 +3465,7 @@ ofproto_rule_expire(struct rule *rule, uint8_t reason)
     struct ofproto *ofproto = rule->ofproto;
     struct ofopgroup *group;
 
-    assert(reason == OFPRR_HARD_TIMEOUT || reason == OFPRR_IDLE_TIMEOUT);
+    ovs_assert(reason == OFPRR_HARD_TIMEOUT || reason == OFPRR_IDLE_TIMEOUT);
 
     ofproto_rule_send_removed(rule, reason);
 
@@ -3503,7 +3499,7 @@ handle_flow_mod(struct ofconn *ofconn, const struct ofp_header *oh)
                               &fm.match.flow, ofproto->max_ports);
     }
     if (!error) {
-        error = handle_flow_mod__(ofconn_get_ofproto(ofconn), ofconn, &fm, oh);
+        error = handle_flow_mod__(ofproto, ofconn, &fm, oh);
     }
     if (error) {
         goto exit_free_ofpacts;
@@ -3547,7 +3543,7 @@ handle_flow_mod__(struct ofproto *ofproto, struct ofconn *ofconn,
                   const struct ofp_header *oh)
 {
     if (ofproto->n_pending >= 50) {
-        assert(!list_is_empty(&ofproto->pending));
+        ovs_assert(!list_is_empty(&ofproto->pending));
         return OFPROTO_POSTPONE;
     }
 
@@ -3866,7 +3862,7 @@ ofproto_collect_ofmonitor_refresh_rules(const struct ofmonitor *m,
 
         cls_cursor_init(&cursor, &table->cls, &target);
         CLS_CURSOR_FOR_EACH (rule, cr, &cursor) {
-            assert(!rule->pending); /* XXX */
+            ovs_assert(!rule->pending); /* XXX */
             ofproto_collect_ofmonitor_refresh_rule(m, rule, seqno, rules);
         }
     }
@@ -4172,7 +4168,7 @@ ofopgroup_create(struct ofproto *ofproto, struct ofconn *ofconn,
     if (ofconn) {
         size_t request_len = ntohs(request->length);
 
-        assert(ofconn_get_ofproto(ofconn) == ofproto);
+        ovs_assert(ofconn_get_ofproto(ofconn) == ofproto);
 
         ofconn_add_opgroup(ofconn, &group->ofconn_node);
         group->ofconn = ofconn;
@@ -4210,7 +4206,7 @@ ofopgroup_complete(struct ofopgroup *group)
     struct ofoperation *op, *next_op;
     int error;
 
-    assert(!group->n_running);
+    ovs_assert(!group->n_running);
 
     error = 0;
     LIST_FOR_EACH (op, group_node, &group->ops) {
@@ -4229,7 +4225,7 @@ ofopgroup_complete(struct ofopgroup *group)
                 error = ofconn_pktbuf_retrieve(group->ofconn, group->buffer_id,
                                                &packet, &in_port);
                 if (packet) {
-                    assert(!error);
+                    ovs_assert(!error);
                     error = rule_execute(op->rule, in_port, packet);
                 }
                 break;
@@ -4289,7 +4285,7 @@ ofopgroup_complete(struct ofopgroup *group)
             break;
 
         case OFOPERATION_DELETE:
-            assert(!op->error);
+            ovs_assert(!op->error);
             ofproto_rule_destroy__(rule);
             op->rule = NULL;
             break;
@@ -4319,7 +4315,7 @@ ofopgroup_complete(struct ofopgroup *group)
     ofmonitor_flush(ofproto->connmgr);
 
     if (!list_is_empty(&group->ofproto_node)) {
-        assert(ofproto->n_pending > 0);
+        ovs_assert(ofproto->n_pending > 0);
         ofproto->n_pending--;
         list_remove(&group->ofproto_node);
     }
@@ -4350,7 +4346,7 @@ ofoperation_create(struct ofopgroup *group, struct rule *rule,
     struct ofproto *ofproto = group->ofproto;
     struct ofoperation *op;
 
-    assert(!rule->pending);
+    ovs_assert(!rule->pending);
 
     op = rule->pending = xzalloc(sizeof *op);
     op->group = group;
@@ -4420,9 +4416,9 @@ ofoperation_complete(struct ofoperation *op, enum ofperr error)
 {
     struct ofopgroup *group = op->group;
 
-    assert(op->rule->pending == op);
-    assert(group->n_running > 0);
-    assert(!error || op->type != OFOPERATION_DELETE);
+    ovs_assert(op->rule->pending == op);
+    ovs_assert(group->n_running > 0);
+    ovs_assert(!error || op->type != OFOPERATION_DELETE);
 
     op->error = error;
     if (!--group->n_running && !list_is_empty(&group->ofproto_node)) {
@@ -4433,7 +4429,7 @@ ofoperation_complete(struct ofoperation *op, enum ofperr error)
 struct rule *
 ofoperation_get_victim(struct ofoperation *op)
 {
-    assert(op->type == OFOPERATION_ADD);
+    ovs_assert(op->type == OFOPERATION_ADD);
     return op->victim;
 }
 \f
@@ -4733,7 +4729,7 @@ oftable_init(struct oftable *table)
 static void
 oftable_destroy(struct oftable *table)
 {
-    assert(classifier_is_empty(&table->cls));
+    ovs_assert(classifier_is_empty(&table->cls));
     oftable_disable_eviction(table);
     classifier_destroy(&table->cls);
     free(table->name);
@@ -4960,7 +4956,7 @@ ofproto_port_set_realdev(struct ofproto *ofproto, uint16_t vlandev_ofp_port,
     struct ofport *ofport;
     int error;
 
-    assert(vlandev_ofp_port != realdev_ofp_port);
+    ovs_assert(vlandev_ofp_port != realdev_ofp_port);
 
     ofport = ofproto_get_port(ofproto, vlandev_ofp_port);
     if (!ofport) {
index 300c247..027e9e1 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <limits.h>
 
 #include "column.h"
@@ -154,7 +153,7 @@ ovsdb_execute(struct ovsdb *db, const struct ovsdb_session *session,
                                          op_name);
             }
         } else {
-            assert(ovsdb_parser_has_error(&parser));
+            ovs_assert(ovsdb_parser_has_error(&parser));
         }
 
         /* A parse error overrides any other error.
index 43fcb95..fd646f0 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "file.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -129,7 +128,7 @@ ovsdb_file_open_log(const char *file_name, enum ovsdb_log_open_mode open_mode,
     struct ovsdb_error *error;
     struct json *json = NULL;
 
-    assert(logp || schemap);
+    ovs_assert(logp || schemap);
 
     error = ovsdb_log_open(file_name, open_mode, -1, &log);
     if (error) {
@@ -194,7 +193,7 @@ ovsdb_file_open__(const char *file_name,
     struct ovsdb *db = NULL;
 
     /* In read-only mode there is no ovsdb_file so 'filep' must be null. */
-    assert(!(read_only && filep));
+    ovs_assert(!(read_only && filep));
 
     open_mode = read_only ? OVSDB_LOG_READ_ONLY : OVSDB_LOG_READ_WRITE;
     error = ovsdb_file_open_log(file_name, open_mode, &log,
@@ -504,7 +503,7 @@ ovsdb_file_save_copy(const char *file_name, int locking,
 struct ovsdb_error *
 ovsdb_file_read_schema(const char *file_name, struct ovsdb_schema **schemap)
 {
-    assert(schemap != NULL);
+    ovs_assert(schemap != NULL);
     return ovsdb_file_open_log(file_name, OVSDB_LOG_READ_ONLY, NULL, schemap);
 }
 \f
@@ -562,7 +561,7 @@ ovsdb_file_create(struct ovsdb *db, struct ovsdb_log *log,
 static struct ovsdb_file *
 ovsdb_file_cast(struct ovsdb_replica *replica)
 {
-    assert(replica->class == &ovsdb_file_class);
+    ovs_assert(replica->class == &ovsdb_file_class);
     return CONTAINER_OF(replica, struct ovsdb_file, replica);
 }
 
index 8e1c030..1d0b0e3 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "jsonrpc-server.h"
 
-#include <assert.h>
 #include <errno.h>
 
 #include "bitmap.h"
@@ -1292,7 +1291,7 @@ ovsdb_jsonrpc_monitor_remove_all(struct ovsdb_jsonrpc_session *s)
 static struct ovsdb_jsonrpc_monitor *
 ovsdb_jsonrpc_monitor_cast(struct ovsdb_replica *replica)
 {
-    assert(replica->class == &ovsdb_jsonrpc_replica_class);
+    ovs_assert(replica->class == &ovsdb_jsonrpc_replica_class);
     return CONTAINER_OF(replica, struct ovsdb_jsonrpc_monitor, replica);
 }
 
index b79535a..440e8d0 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "log.h"
 
-#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
@@ -75,7 +74,7 @@ ovsdb_log_open(const char *name, enum ovsdb_log_open_mode open_mode,
 
     *filep = NULL;
 
-    assert(locking == -1 || locking == false || locking == true);
+    ovs_assert(locking == -1 || locking == false || locking == true);
     if (locking < 0) {
         locking = open_mode != OVSDB_LOG_READ_ONLY;
     }
@@ -318,7 +317,7 @@ error:
 void
 ovsdb_log_unread(struct ovsdb_log *file)
 {
-    assert(file->mode == OVSDB_LOG_READ);
+    ovs_assert(file->mode == OVSDB_LOG_READ);
     file->offset = file->prev_offset;
 }
 
index d5d2189..37bd1aa 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <getopt.h>
index 478109a..dc0839e 100755 (executable)
@@ -185,10 +185,10 @@ def printCIDLSource(schemaFile):
 
 #include <config.h>
 #include %s
-#include <assert.h>
 #include <limits.h>
 #include "ovsdb-data.h"
 #include "ovsdb-error.h"
+#include "util.h"
 
 #ifdef __CHECKER__
 /* Sparse dislikes sizeof(bool) ("warning: expression using sizeof bool"). */
@@ -236,7 +236,7 @@ static void
             if type.is_smap():
                 print "    size_t i;"
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    smap_init(&row->%s);" % columnName
                 print "    for (i = 0; i < datum->n; i++) {"
                 print "        smap_add(&row->%s," % columnName
@@ -245,7 +245,7 @@ static void
                 print "    }"
             elif (type.n_min == 1 and type.n_max == 1) or type.is_optional_pointer():
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    if (datum->n >= 1) {"
                 if not type.key.ref_table:
                     print "        %s = datum->keys[0].%s;" % (keyVar, type.key.type.to_string())
@@ -270,7 +270,7 @@ static void
                     nMax = "datum->n"
                 print "    size_t i;"
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    %s = NULL;" % keyVar
                 if valueVar:
                     print "    %s = NULL;" % valueVar
@@ -333,7 +333,7 @@ static void
 {
     struct %(s)s *row = %(s)s_cast(row_);
 
-    assert(inited);''' % {'s': structName, 'c': columnName}
+    ovs_assert(inited);''' % {'s': structName, 'c': columnName}
 
                 if type.is_smap():
                     print "    smap_destroy(&row->%s);" % columnName
@@ -415,7 +415,7 @@ struct %(s)s *
 void
 %(s)s_verify_%(c)s(const struct %(s)s *row)
 {
-    assert(inited);
+    ovs_assert(inited);
     ovsdb_idl_txn_verify(&row->header_, &%(s)s_columns[%(S)s_COL_%(C)s]);
 }''' % {'s': structName,
         'S': structName.upper(),
@@ -426,7 +426,7 @@ void
         for columnName, column in sorted(table.columns.iteritems()):
             if column.type.value:
                 valueParam = ',\n\tenum ovsdb_atomic_type value_type OVS_UNUSED'
-                valueType = '\n    assert(value_type == %s);' % column.type.value.toAtomicType()
+                valueType = '\n    ovs_assert(value_type == %s);' % column.type.value.toAtomicType()
                 valueComment = "\n * 'value_type' must be %s." % column.type.value.toAtomicType()
             else:
                 valueParam = ''
@@ -452,7 +452,7 @@ const struct ovsdb_datum *
 %(s)s_get_%(c)s(const struct %(s)s *row,
 \tenum ovsdb_atomic_type key_type OVS_UNUSED%(v)s)
 {
-    assert(key_type == %(kt)s);%(vt)s
+    ovs_assert(key_type == %(kt)s);%(vt)s
     return ovsdb_idl_read(&row->header_, &%(s)s_col_%(c)s);
 }""" % {'s': structName, 'c': columnName,
        'kt': column.type.key.toAtomicType(),
@@ -469,7 +469,7 @@ void
 {
     struct ovsdb_datum datum;
 
-    assert(inited);
+    ovs_assert(inited);
     if (smap) {
         struct smap_node *node;
         size_t i;
@@ -518,7 +518,7 @@ void
             print "    struct ovsdb_datum datum;"
             if type.n_min == 1 and type.n_max == 1:
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    datum.n = 1;"
                 print "    datum.keys = xmalloc(sizeof *datum.keys);"
                 print "    " + type.key.copyCValue("datum.keys[0].%s" % type.key.type.to_string(), keyVar)
@@ -529,7 +529,7 @@ void
                     print "    datum.values = NULL;"
             elif type.is_optional_pointer():
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    if (%s) {" % keyVar
                 print "        datum.n = 1;"
                 print "        datum.keys = xmalloc(sizeof *datum.keys);"
@@ -542,7 +542,7 @@ void
             else:
                 print "    size_t i;"
                 print
-                print "    assert(inited);"
+                print "    ovs_assert(inited);"
                 print "    datum.n = %s;" % nVar
                 print "    datum.keys = xmalloc(%s * sizeof *datum.keys);" % nVar
                 if type.value:
index 6032d73..2657e26 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <errno.h>
 #include <getopt.h>
 #include <signal.h>
index 450c327..9b9f96a 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "row.h"
 
-#include <assert.h>
 #include <stddef.h>
 
 #include "dynamic-string.h"
@@ -376,7 +375,7 @@ ovsdb_row_hash_contains_all(const struct ovsdb_row_hash *a,
 {
     struct ovsdb_row_hash_node *node;
 
-    assert(ovsdb_column_set_equals(&a->columns, &b->columns));
+    ovs_assert(ovsdb_column_set_equals(&a->columns, &b->columns));
     HMAP_FOR_EACH (node, hmap_node, &b->rows) {
         if (!ovsdb_row_hash_contains__(a, node->row, node->hmap_node.hash)) {
             return false;
index ac2aa29..bf4ef3c 100644 (file)
@@ -17,8 +17,6 @@
 
 #include "server.h"
 
-#include <assert.h>
-
 #include "hash.h"
 #include "ovsdb.h"
 
@@ -35,7 +33,7 @@ ovsdb_session_init(struct ovsdb_session *session, struct ovsdb_server *server)
 void
 ovsdb_session_destroy(struct ovsdb_session *session)
 {
-    assert(hmap_is_empty(&session->waiters));
+    ovs_assert(hmap_is_empty(&session->waiters));
     hmap_destroy(&session->waiters);
 }
 
@@ -101,7 +99,7 @@ ovsdb_lock_waiter_remove(struct ovsdb_lock_waiter *waiter)
 void
 ovsdb_lock_waiter_destroy(struct ovsdb_lock_waiter *waiter)
 {
-    assert(!waiter->lock);
+    ovs_assert(!waiter->lock);
     hmap_remove(&waiter->session->waiters, &waiter->session_node);
     free(waiter->lock_name);
     free(waiter);
index 19f4d31..0d4f522 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2010, 2011 Nicira, Inc.
+/* 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.
@@ -17,7 +17,6 @@
 
 #include "table.h"
 
-#include <assert.h>
 #include <limits.h>
 
 #include "json.h"
@@ -30,7 +29,7 @@
 static void
 add_column(struct ovsdb_table_schema *ts, struct ovsdb_column *column)
 {
-    assert(!shash_find(&ts->columns, column->name));
+    ovs_assert(!shash_find(&ts->columns, column->name));
     column->index = shash_count(&ts->columns);
     shash_add(&ts->columns, column->name, column);
 }
@@ -51,11 +50,11 @@ ovsdb_table_schema_create(const char *name, bool mutable,
 
     uuid = ovsdb_column_create("_uuid", false, true, &ovsdb_type_uuid);
     add_column(ts, uuid);
-    assert(uuid->index == OVSDB_COL_UUID);
+    ovs_assert(uuid->index == OVSDB_COL_UUID);
 
     version = ovsdb_column_create("_version", false, false, &ovsdb_type_uuid);
     add_column(ts, version);
-    assert(version->index == OVSDB_COL_VERSION);
+    ovs_assert(version->index == OVSDB_COL_VERSION);
 
     ts->n_indexes = 0;
     ts->indexes = NULL;
index cc890ad..646163a 100644 (file)
@@ -17,8 +17,6 @@
 
 #include "transaction.h"
 
-#include <assert.h>
-
 #include "bitmap.h"
 #include "dynamic-string.h"
 #include "hash.h"
@@ -111,7 +109,7 @@ ovsdb_txn_create(struct ovsdb *db)
 static void
 ovsdb_txn_free(struct ovsdb_txn *txn)
 {
-    assert(list_is_empty(&txn->txn_tables));
+    ovs_assert(list_is_empty(&txn->txn_tables));
     ds_destroy(&txn->comment);
     free(txn);
 }
@@ -807,7 +805,7 @@ ovsdb_txn_commit(struct ovsdb_txn *txn, bool durable)
         if (error) {
             /* We don't support two-phase commit so only the first replica is
              * allowed to report an error. */
-            assert(&replica->node == txn->db->replicas.next);
+            ovs_assert(&replica->node == txn->db->replicas.next);
 
             ovsdb_txn_abort(txn);
             return error;
@@ -898,7 +896,7 @@ ovsdb_txn_row_modify(struct ovsdb_txn *txn, const struct ovsdb_row *ro_row_)
     struct ovsdb_row *ro_row = CONST_CAST(struct ovsdb_row *, ro_row_);
 
     if (ro_row->txn_row) {
-        assert(ro_row == ro_row->txn_row->new);
+        ovs_assert(ro_row == ro_row->txn_row->new);
         return ro_row;
     } else {
         struct ovsdb_table *table = ro_row->table;
@@ -940,7 +938,7 @@ ovsdb_txn_row_delete(struct ovsdb_txn *txn, const struct ovsdb_row *row_)
     if (!txn_row) {
         ovsdb_txn_row_create(txn, table, row, NULL);
     } else {
-        assert(txn_row->new == row);
+        ovs_assert(txn_row->new == row);
         if (txn_row->old) {
             txn_row->new = NULL;
         } else {
@@ -987,7 +985,7 @@ ovsdb_txn_table_destroy(struct ovsdb_txn_table *txn_table)
 {
     size_t i;
 
-    assert(hmap_is_empty(&txn_table->txn_rows));
+    ovs_assert(hmap_is_empty(&txn_table->txn_rows));
 
     for (i = 0; i < txn_table->table->schema->n_indexes; i++) {
         hmap_destroy(&txn_table->txn_indexes[i]);
index a93b844..74a1b0f 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "trigger.h"
 
-#include <assert.h>
 #include <limits.h>
 
 #include "json.h"
@@ -124,7 +123,7 @@ ovsdb_trigger_try(struct ovsdb_trigger *t, long long int now)
 static void
 ovsdb_trigger_complete(struct ovsdb_trigger *t)
 {
-    assert(t->result != NULL);
+    ovs_assert(t->result != NULL);
     list_remove(&t->node);
     list_push_back(&t->session->completions, &t->node);
 }
index 8fecbc7..7bfefc4 100644 (file)
@@ -70,9 +70,44 @@ def make_unix_socket(style, nonblock, bind_path, connect_path):
         return 0, sock
     except socket.error, e:
         sock.close()
-        if bind_path is not None:
+        if (bind_path is not None and
+            os.path.exists(bind_path)):
             ovs.fatal_signal.unlink_file_now(bind_path)
-        return get_exception_errno(e), None
+        eno = ovs.socket_util.get_exception_errno(e)
+        if (eno == "AF_UNIX path too long" and
+            os.uname()[0] == "Linux"):
+            short_connect_path = None
+            short_bind_path = None
+            connect_dirfd = None
+            bind_dirfd = None
+            # Try workaround using /proc/self/fd
+            if connect_path is not None:
+                dirname = os.path.dirname(connect_path)
+                basename = os.path.basename(connect_path)
+                try:
+                    connect_dirfd = os.open(dirname, os.O_DIRECTORY | os.O_RDONLY)
+                except OSError, err:
+                    return get_exception_errno(e), None
+                short_connect_path = "/proc/self/fd/%d/%s" % (connect_dirfd, basename)
+
+            if bind_path is not None:
+                dirname = os.path.dirname(bind_path)
+                basename = os.path.basename(bind_path)
+                try:
+                    bind_dirfd = os.open(dirname, os.O_DIRECTORY | os.O_RDONLY)
+                except OSError, err:
+                    return get_exception_errno(e), None
+                short_bind_path = "/proc/self/fd/%d/%s" % (bind_dirfd, basename)
+
+            try:
+                return make_unix_socket(style, nonblock, short_bind_path, short_connect_path)
+            finally:
+                if connect_dirfd is not None:
+                    os.close(connect_dirfd)
+                if bind_dirfd is not None:
+                    os.close(bind_dirfd)
+        else:
+            return get_exception_errno(e), None
 
 
 def check_connection_completion(sock):
index 732839c..23c36ef 100644 (file)
@@ -210,7 +210,7 @@ tests_test_jsonrpc_LDADD = lib/libopenvswitch.a $(SSL_LIBS)
 
 noinst_PROGRAMS += tests/test-list
 tests_test_list_SOURCES = tests/test-list.c
-tests_test_list_LDADD = lib/libopenvswitch.a
+tests_test_list_LDADD = lib/libopenvswitch.a $(SSL_LIBS)
 
 noinst_PROGRAMS += tests/test-lockfile
 tests_test_lockfile_SOURCES = tests/test-lockfile.c
index 0765c3f..55adcfb 100644 (file)
@@ -140,3 +140,22 @@ mkdir 01234567890123456789012345678901234567890123456789012345678901234567890123
 cd 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
 AT_CHECK([test-unix-socket ../012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789/socket socket])
 AT_CLEANUP
+
+AT_SETUP([ovs_assert])
+OVS_LOGDIR=`pwd`; export OVS_LOGDIR
+AT_CHECK([test-util -voff -vfile:info '-vPATTERN:file:%c|%p|%m' --log-file assert || kill -l $?],
+  [0], [ABRT
+], [stderr])
+
+AT_CHECK([sed 's/\(opened log file\) .*/\1/
+s/|[[^|]]*: /|/' test-util.log], [0], [dnl
+vlog|INFO|opened log file
+util|EMER|assertion false failed in test_assert()
+])
+
+AT_CHECK([sed 's/.*: //
+1q' stderr], [0],
+  [assertion false failed in test_assert()
+])
+
+AT_CLEANUP
index 009ac36..687f9c9 100644 (file)
@@ -32,7 +32,7 @@ skb_mark(0x1234),in_port(1),eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15),eth
 
  echo
  echo '# Valid forms with tunnel header.'
- sed 's/^/ipv4_tunnel(tun_id=0x7f10354,src=10.10.10.10,dst=20.20.20.20,tos=0x0,ttl=64,flags(csum,key)),/' odp-base.txt
+ sed 's/^/tunnel(tun_id=0x7f10354,src=10.10.10.10,dst=20.20.20.20,tos=0x0,ttl=64,flags(csum,key)),/' odp-base.txt
 
  echo
  echo '# Valid forms with VLAN header.'
@@ -45,13 +45,13 @@ s/$/)/' odp-base.txt
 
  echo
  echo '# Valid forms with tunnel and VLAN headers.'
- sed 's/^/ipv4_tunnel(tun_id=0xfedcba9876543210,src=10.0.0.1,dst=10.0.0.2,tos=0x8,ttl=128,flags()),/
+ sed 's/^/tunnel(tun_id=0xfedcba9876543210,src=10.0.0.1,dst=10.0.0.2,tos=0x8,ttl=128,flags(key)),/
 s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/
 s/$/)/' odp-base.txt
 
  echo
  echo '# Valid forms with QOS priority, tunnel, and VLAN headers.'
- sed 's/^/skb_priority(0x1234),ipv4_tunnel(tun_id=0xfedcba9876543210,src=10.10.10.10,dst=20.20.20.20,tos=0x8,ttl=64,flags(key)),/
+ sed 's/^/skb_priority(0x1234),tunnel(tun_id=0xfedcba9876543210,src=10.10.10.10,dst=20.20.20.20,tos=0x8,ttl=64,flags(key)),/
 s/\(eth([[^)]]*)\),*/\1,eth_type(0x8100),vlan(vid=99,pcp=7),encap(/
 s/$/)/' odp-base.txt
 
@@ -92,9 +92,8 @@ push_vlan(tpid=0x9100,vid=13,pcp=5)
 push_vlan(tpid=0x9100,vid=13,pcp=5,cfi=0)
 pop_vlan
 sample(sample=9.7%,actions(1,2,3,push_vlan(vid=1,pcp=2)))
-set(ipv4_tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags(df,csum,key)))
-set(ipv4_tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags(df,csum,key,0x20)))
-set(ipv4_tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags()))
+set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags(df,csum,key)))
+set(tunnel(tun_id=0xabcdef1234567890,src=1.1.1.1,dst=2.2.2.2,tos=0x0,ttl=64,flags(key)))
 ])
 AT_CHECK_UNQUOTED([test-odp parse-actions < actions.txt], [0],
   [`cat actions.txt`
index fd66d24..a14c412 100644 (file)
@@ -601,15 +601,12 @@ AT_CLEANUP
 
 
 AT_SETUP([ofproto-dpif - mirroring, select_all])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
-        add-port br0 p3 -- set Interface p3 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p3 get Port p3 --\
-        --id=@m create Mirror name=mymirror \
-        select_all=true output_port=@p3], [<0>
-])
+        --id=@m create Mirror name=mymirror select_all=true output_port=@p3
 
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
@@ -634,15 +631,12 @@ AT_CLEANUP
 
 
 AT_SETUP([ofproto-dpif - mirroring, select_src])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
-        add-port br0 p3 -- set Interface p3 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p1 get Port p1 -- --id=@p3 get Port p3 --\
-        --id=@m create Mirror name=mymirror \
-        select_src_port=@p1 output_port=@p3], [<0>
-])
+        --id=@m create Mirror name=mymirror select_src_port=@p1 output_port=@p3
 
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
@@ -665,14 +659,12 @@ OVS_VSWITCHD_STOP
 AT_CLEANUP
 
 AT_SETUP([ofproto-dpif - mirroring, OFPP_NONE ingress port])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p2 get Port p2 --\
-        --id=@m create Mirror name=mymirror \
-        select_all=true output_port=@p2], [<0>
-])
+        --id=@m create Mirror name=mymirror select_all=true output_port=@p2
 
 AT_CHECK([ovs-ofctl add-flow br0 action=output:1])
 
@@ -688,15 +680,12 @@ AT_CLEANUP
 
 
 AT_SETUP([ofproto-dpif - mirroring, select_dst])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 --\
-        add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2 --\
-        add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3 --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p2 get Port p2 -- --id=@p3 get Port p3 --\
-        --id=@m create Mirror name=mymirror \
-        select_dst_port=@p2 output_port=@p3], [<0>
-])
+        --id=@m create Mirror name=mymirror select_dst_port=@p2 output_port=@p3
 
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
@@ -721,15 +710,12 @@ AT_CLEANUP
 
 
 AT_SETUP([ofproto-dpif - mirroring, select_vlan])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
-        add-port br0 p3 -- set Interface p3 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p2 get Port p2 -- --id=@p3 get Port p3 --\
-        --id=@m create Mirror name=mymirror \
-        select_all=true select_vlan=11 output_port=@p3], [<0>
-])
+        --id=@m create Mirror name=mymirror select_all=true select_vlan=11 output_port=@p3
 
 AT_DATA([flows.txt], [dnl
 in_port=1, actions=output:2
@@ -759,15 +745,12 @@ AT_CLEANUP
 
 
 AT_SETUP([ofproto-dpif - mirroring, output_port])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
-        add-port br0 p3 -- set Interface p3 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2, 3)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
         --id=@p3 get Port p3 --\
-        --id=@m create Mirror name=mymirror \
-        select_all=true output_port=@p3], [<0>
-])
+        --id=@m create Mirror name=mymirror select_all=true output_port=@p3
 
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=mod_vlan_vid:17,output:2
@@ -791,13 +774,11 @@ OVS_VSWITCHD_STOP
 AT_CLEANUP
 
 AT_SETUP([ofproto-dpif - mirroring, output_vlan])
-OVS_VSWITCHD_START(
-       [add-port br0 p1 -- set Interface p1 type=dummy --\
-        add-port br0 p2 -- set Interface p2 type=dummy --\
+OVS_VSWITCHD_START
+ADD_OF_PORTS([br0], 1, 2)
+ovs-vsctl \
         set Bridge br0 mirrors=@m --\
-        --id=@m create Mirror name=mymirror \
-        select_all=true output_vlan=12], [<0>
-])
+        --id=@m create Mirror name=mymirror select_all=true output_vlan=12
 
 AT_DATA([flows.txt], [dnl
 in_port=1 actions=output:2
@@ -838,11 +819,8 @@ m4_define([OFPROTO_TRACE],
      [0], [expout])])
 
 AT_SETUP([ofproto-dpif - MAC learning])
-OVS_VSWITCHD_START(
-  [set bridge br0 fail-mode=standalone -- \
-   add-port br0 p1 -- set Interface p1 type=dummy -- \
-   add-port br0 p2 -- set Interface p2 type=dummy -- \
-   add-port br0 p3 -- set Interface p3 type=dummy])
+OVS_VSWITCHD_START([set bridge br0 fail-mode=standalone])
+ADD_OF_PORTS([br0], 1, 2, 3)
 
 arp='eth_type(0x0806),arp(sip=192.168.0.1,tip=192.168.0.2,op=1,sha=50:54:00:00:00:05,tha=00:00:00:00:00:00)'
 
@@ -1002,15 +980,12 @@ AT_SETUP([ofproto-dpif - NetFlow flow expiration])
 AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
 NETFLOW_PORT=`cat stdout`
 
-OVS_VSWITCHD_START(
-  [set Bridge br0 fail-mode=standalone -- \
-   add-port br0 p1 -- set Interface p1 type=dummy -- \
-   add-port br0 p2 -- set Interface p2 type=dummy -- \
+OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
+ADD_OF_PORTS([br0], 1, 2)
+ovs-vsctl \
    set Bridge br0 netflow=@nf -- \
    --id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
-     engine_id=1 engine_type=2 active_timeout=30 \
-     add-id-to-interface=false], [<0>
-])
+     engine_id=1 engine_type=2 active_timeout=30 add-id-to-interface=false
 
 ON_EXIT([kill `cat test-netflow.pid`])
 AT_CHECK([test-netflow --detach --no-chdir --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])
@@ -1047,15 +1022,12 @@ AT_SETUP([ofproto-dpif - NetFlow active expiration])
 AT_CHECK([perl $srcdir/choose-port.pl], [0], [stdout])
 NETFLOW_PORT=`cat stdout`
 
-OVS_VSWITCHD_START(
-  [set Bridge br0 fail-mode=standalone -- \
-   add-port br0 p1 -- set Interface p1 type=dummy -- \
-   add-port br0 p2 -- set Interface p2 type=dummy -- \
+OVS_VSWITCHD_START([set Bridge br0 fail-mode=standalone])
+ADD_OF_PORTS([br0], 1, 2)
+ovs-vsctl \
    set Bridge br0 netflow=@nf -- \
    --id=@nf create NetFlow targets=\"127.0.0.1:$NETFLOW_PORT\" \
-     engine_id=1 engine_type=2 active_timeout=10 \
-     add-id-to-interface=false], [<0>
-])
+     engine_id=1 engine_type=2 active_timeout=10 add-id-to-interface=false
 
 ON_EXIT([kill `test-netflow.pid`])
 AT_CHECK([test-netflow --detach --no-chdir --pidfile $NETFLOW_PORT:127.0.0.1 > netflow.log])AT_CAPTURE_FILE([netflow.log])
index 6a1cc35..326d5a4 100644 (file)
@@ -666,6 +666,18 @@ AT_CHECK([RUN_OVS_VSCTL_TOGETHER([destroy b br0],
   [0], [stdout], [], [OVS_VSCTL_CLEANUP])
 AT_CHECK([RUN_OVS_VSCTL([list b])], 
   [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists get b x datapath_id])],
+  [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists list b x])],
+  [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([--if-exists set controller x connection_mode=standalone])],
+  [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK(
+  [RUN_OVS_VSCTL([--if-exists remove netflow x targets '"1.2.3.4:567"'])],
+  [0], [], [], [OVS_VSCTL_CLEANUP])
+AT_CHECK(
+  [RUN_OVS_VSCTL([--if-exists clear netflow x targets])],
+  [0], [], [], [OVS_VSCTL_CLEANUP])
 OVS_VSCTL_CLEANUP
 AT_CLEANUP
 
@@ -713,6 +725,9 @@ AT_CHECK([RUN_OVS_VSCTL([list interx x])],
 AT_CHECK([RUN_OVS_VSCTL([list b x])], 
   [1], [], [ovs-vsctl: no row "x" in table Bridge
 ], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([get b x datapath_id])],
+  [1], [], [ovs-vsctl: no row "x" in table Bridge
+], [OVS_VSCTL_CLEANUP])
 AT_CHECK([RUN_OVS_VSCTL([get b br0 d])], 
   [1], [], [ovs-vsctl: Bridge contains more than one column whose name matches "d"
 ], [OVS_VSCTL_CLEANUP])
@@ -728,6 +743,9 @@ AT_CHECK([RUN_OVS_VSCTL([get b br0 datapath_id:y=z])],
 AT_CHECK([RUN_OVS_VSCTL([set b br0 'datapath_id:y>=z'])], 
   [1], [], [ovs-vsctl: datapath_id:y>=z: argument does not end in "=" followed by a value.
 ], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([set controller x connection_mode=standalone])],
+  [1], [], [ovs-vsctl: no row "x" in table Controller
+], [OVS_VSCTL_CLEANUP])
 AT_CHECK([RUN_OVS_VSCTL([wait-until b br0 datapath_id:y,z])], 
   [1], [], [ovs-vsctl: datapath_id:y,z: argument does not end in "=", "!=", "<", ">", "<=", ">=", "{=}", "{!=}", "{<}", "{>}", "{<=}", or "{>=}" followed by a value.
 ], [OVS_VSCTL_CLEANUP])
@@ -758,6 +776,12 @@ AT_CHECK([RUN_OVS_VSCTL([add b br1 datapath_id x y])],
 AT_CHECK([RUN_OVS_VSCTL([remove netflow `cat netflow-uuid` targets '"1.2.3.4:567"'])], 
   [1], [], [ovs-vsctl: "remove" operation would put 0 values in column targets of table NetFlow but the minimum number is 1
 ], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([remove netflow x targets '"1.2.3.4:567"'])], 
+  [1], [], [ovs-vsctl: no row "x" in table NetFlow
+], [OVS_VSCTL_CLEANUP])
+AT_CHECK([RUN_OVS_VSCTL([clear netflow x targets])],
+  [1], [], [ovs-vsctl: no row "x" in table NetFlow
+], [OVS_VSCTL_CLEANUP])
 AT_CHECK([RUN_OVS_VSCTL([clear netflow `cat netflow-uuid` targets])], 
   [1], [], [ovs-vsctl: "clear" operation cannot be applied to column targets of table NetFlow, which is not allowed to be empty
 ], [OVS_VSCTL_CLEANUP])
index d53ba2e..0b7b87a 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "hash.h"
+#include "jhash.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -41,9 +42,9 @@ hash_words_cb(uint32_t input)
 }
 
 static uint32_t
-mhash_words_cb(uint32_t input)
+jhash_words_cb(uint32_t input)
 {
-    return mhash_words(&input, 1, 0);
+    return jhash_words(&input, 1, 0);
 }
 
 static uint32_t
@@ -130,7 +131,7 @@ main(void)
      * independence must be a bad assumption :-)
      */
     check_word_hash(hash_words_cb, "hash_words", 11);
-    check_word_hash(mhash_words_cb, "mhash_words", 11);
+    check_word_hash(jhash_words_cb, "jhash_words", 11);
 
     /* Check that all hash functions of with one 1-bit (or no 1-bits) set
      * within three 32-bit words have different values in their lowest 12
@@ -146,24 +147,26 @@ main(void)
      * so we are doing pretty well to not have any collisions in 12 bits.
      */
     check_3word_hash(hash_words, "hash_words");
-    check_3word_hash(mhash_words, "mhash_words");
+    check_3word_hash(jhash_words, "jhash_words");
 
     /* Check that all hashes computed with hash_int with one 1-bit (or no
      * 1-bits) set within a single 32-bit word have different values in all
-     * 14-bit consecutive runs.
+     * 12-bit consecutive runs.
      *
      * Given a random distribution, the probability of at least one collision
-     * in any set of 14 bits is approximately
+     * in any set of 12 bits is approximately
      *
-     *                      1 - ((2**14 - 1)/2**14)**C(33,2)
-     *                   == 1 - (16,383/16,834)**528
-     *                   =~ 0.031
+     *                      1 - ((2**12 - 1)/2**12)**C(33,2)
+     *                   == 1 - (4,095/4,096)**528
+     *                   =~ 0.12
      *
-     * There are 18 ways to pick 14 consecutive bits in a 32-bit word, so if we
+     * There are 20 ways to pick 12 consecutive bits in a 32-bit word, so if we
      * assumed independence then the chance of having no collisions in any of
-     * those 14-bit runs would be (1-0.03)**18 =~ 0.56.  This seems reasonable.
+     * those 12-bit runs would be (1-0.12)**20 =~ 0.078.  This refutes our
+     * assumption of independence, which makes it seem like a good hash
+     * function.
      */
-    check_word_hash(hash_int_cb, "hash_int", 14);
+    check_word_hash(hash_int_cb, "hash_int", 12);
 
     return 0;
 }
index b98fc79..3eecc7a 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <config.h>
 
+#include <getopt.h>
 #include <inttypes.h>
 #include <limits.h>
 #include <stdio.h>
@@ -25,6 +26,7 @@
 #include "command-line.h"
 #include "random.h"
 #include "util.h"
+#include "vlog.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -335,6 +337,12 @@ test_follow_symlinks(int argc, char *argv[])
         free(target);
     }
 }
+
+static void
+test_assert(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
+{
+    ovs_assert(false);
+}
 \f
 static const struct command commands[] = {
     {"ctz", 0, 0, test_ctz},
@@ -345,13 +353,46 @@ static const struct command commands[] = {
     {"bitwise_one", 0, 0, test_bitwise_one},
     {"bitwise_is_all_zeros", 0, 0, test_bitwise_is_all_zeros},
     {"follow-symlinks", 1, INT_MAX, test_follow_symlinks},
+    {"assert", 0, 0, test_assert},
     {NULL, 0, 0, NULL},
 };
 
+static void
+parse_options(int argc, char *argv[])
+{
+    enum {
+        VLOG_OPTION_ENUMS
+    };
+    static struct option long_options[] = {
+        VLOG_LONG_OPTIONS,
+        {NULL, 0, NULL, 0},
+    };
+    char *short_options = long_options_to_short_options(long_options);
+
+    for (;;) {
+        int c = getopt_long(argc, argv, short_options, long_options, NULL);
+        if (c == -1) {
+            break;
+        }
+
+        switch (c) {
+        VLOG_OPTION_HANDLERS
+
+        case '?':
+            exit(EXIT_FAILURE);
+
+        default:
+            abort();
+        }
+    }
+    free(short_options);
+}
+
 int
 main(int argc, char *argv[])
 {
     set_program_name(argv[0]);
-    run_command(argc - 1, argv + 1, commands);
+    parse_options(argc, argv);
+    run_command(argc - optind, argv + optind, commands);
     return 0;
 }
index bce74a6..78f67a3 100755 (executable)
@@ -267,16 +267,27 @@ internal_interfaces () {
     done
 }
 
-save_flows () {
-   if set X `ovs_vsctl -- --real list-br`; then
-        shift
-        if "$datadir/scripts/ovs-save" save-flows "$@" > "$script_flows"; then
-            chmod +x "$script_flows"
-            return 0
-        fi
+ovs_save () {
+    bridges=`ovs_vsctl -- --real list-br`
+    if [ -n "${bridges}" ] && \
+        "$datadir/scripts/ovs-save" "$1" ${bridges} > "$2"; then
+        chmod +x "$2"
+        return 0
     fi
-    script_flows=
-    return 1
+    eval $3=""
+    [ -z "${bridges}" ] && return 0
+}
+
+save_ofports_if_required () {
+    # Save ofports if we are upgrading from a pre-1.10 branch.
+    case `ovs-appctl version | sed 1q` in
+        "ovs-vswitchd (Open vSwitch) 1."[0-9].*)
+            action "Saving ofport values" ovs_save save-ofports \
+                "${script_ofports}" script_ofports
+            ;;
+        *)
+            ;;
+    esac
 }
 
 save_interfaces () {
@@ -284,6 +295,11 @@ save_interfaces () {
         > "${script_interfaces}"
 }
 
+restore_ofports () {
+    [ -n "${script_ofports}" ] && \
+        action "Restoring ofport values" "${script_ofports}"
+}
+
 restore_flows () {
     [ -n "${script_flows}" ] && \
         action "Restoring saved flows" "${script_flows}"
@@ -295,15 +311,21 @@ force_reload_kmod () {
 
     script_interfaces=`mktemp`
     script_flows=`mktemp`
-    trap 'rm -f "${script_interfaces}" "${script_flows}" ' 0
+    script_ofports=`mktemp`
+    trap 'rm -f "${script_interfaces}" "${script_flows}" "${script_ofports}"' 0
 
-    action "Saving flows" save_flows
+    action "Saving flows" ovs_save save-flows "${script_flows}" script_flows
+
+    save_ofports_if_required
 
     # Restart the database first, since a large database may take a
     # while to load, and we want to minimize forwarding disruption.
     stop_ovsdb
     start_ovsdb
 
+    # Restore of ofports should happen before vswitchd is restarted.
+    restore_ofports
+
     stop_forwarding
 
     if action "Saving interface configuration" save_interfaces; then
@@ -353,7 +375,8 @@ restart () {
         script_flows=`mktemp`
         trap 'rm -f "${script_flows}"' 0
 
-        action "Saving flows" save_flows
+        action "Saving flows" ovs_save save-flows "${script_flows}" \
+            script_flows
     fi
 
     # Restart the database first, since a large database may take a
index 2e32604..b48b349 100644 (file)
@@ -16,7 +16,6 @@
 
 #include <config.h>
 #include <arpa/inet.h>
-#include <assert.h>
 #include <errno.h>
 #include <getopt.h>
 #include <inttypes.h>
@@ -843,7 +842,7 @@ sort_output_actions__(struct nlattr *first, struct nlattr *end)
     size_t bytes = (uint8_t *) end - (uint8_t *) first;
     size_t n = bytes / NL_A_U32_SIZE;
 
-    assert(bytes % NL_A_U32_SIZE == 0);
+    ovs_assert(bytes % NL_A_U32_SIZE == 0);
     qsort(first, n, NL_A_U32_SIZE, compare_output_actions);
 }
 
@@ -964,7 +963,7 @@ dpctl_normalize_actions(int argc, char *argv[])
     HMAP_FOR_EACH (af, hmap_node, &actions_per_flow) {
         afs[i++] = af;
     }
-    assert(i == n_afs);
+    ovs_assert(i == n_afs);
 
     qsort(afs, n_afs, sizeof *afs, compare_actions_for_flow);
 
index 239f317..2ffe3d5 100644 (file)
@@ -2177,7 +2177,7 @@ ofctl_parse_flows__(struct ofputil_flow_mod *fms, size_t n_fms)
             break;
         }
     }
-    assert(IS_POW2(protocol));
+    ovs_assert(IS_POW2(protocol));
 
     printf("chosen protocol: %s\n", ofputil_protocol_to_string(protocol));
 
index 2ab9d08..16ac879 100755 (executable)
@@ -27,6 +27,8 @@ Commands:
                         configuration.
  save-flows             Outputs a shell script on stdout that will restore
                         Openflow flows of each Open vSwitch bridge.
+ save-ofports           Outputs a shell script on stdout that will restore
+                        the ofport value across a force-reload-kmod.
 This script is meant as a helper for the Open vSwitch init script commands.
 EOF
 }
@@ -174,6 +176,32 @@ save_flows () {
     done
 }
 
+ovs_vsctl () {
+    ovs-vsctl --no-wait --timeout=1 "$@"
+}
+
+save_ofports ()
+{
+    if missing_program ovs-vsctl; then
+        echo "$0: ovs-vsctl not found in $PATH" >&2
+        exit 1
+    fi
+
+    for bridge in "$@"; do
+        count=0
+        for iface in `ovs_vsctl list-ifaces ${bridge}`; do
+            ofport=`ovs_vsctl get interface ${iface} ofport`
+            [ "${count}" -eq 0 ] && cmd="ovs-vsctl --no-wait --timeout=1"
+            cmd="${cmd} -- --if-exists set interface "${iface}" \
+                     ofport_request="${ofport}""
+
+            # Run set interface command on 50 ports at a time.
+            count=`expr ${count} + 1`
+            [ "${count}" -eq 50 ] && count=0 && echo "${cmd}" && cmd=""
+        done
+        echo "${cmd}"
+    done
+}
 
 while [ $# -ne 0 ]
 do
@@ -188,6 +216,11 @@ do
             save_interfaces "$@"
             exit 0
             ;;
+        "save-ofports")
+            shift
+            save_ofports "$@"
+            exit 0
+            ;;
         -h | --help)
             usage
             exit 0
index 30baafd..cf6cf88 100644 (file)
@@ -567,13 +567,19 @@ well (but use quotes to prevent the shell from expanding
 other-config=1=y\fR, which may not have the desired effect).
 .
 .ST "Database Command Syntax"
-.IP "[\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBlist \fItable \fR[\fIrecord\fR]..."
+.
+.IP "[\fB\-\-if\-exists\fR] [\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBlist \fItable \fR[\fIrecord\fR]..."
 Lists the data in each specified \fIrecord\fR.  If no
 records are specified, lists all the records in \fItable\fR.
 .IP
 If \fB\-\-columns\fR is specified, only the requested columns are
 listed, in the specified order.  Otherwise, all columns are listed, in
 alphabetical order by column name.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if any specified
+\fIrecord\fR does not exist.  With \fB\-\-if-exists\fR, the command
+ignores any \fIrecord\fR that does not exist, without producing any
+output.
 .
 .IP "[\fB\-\-columns=\fIcolumn\fR[\fB,\fIcolumn\fR]...] \fBfind \fItable \fR[\fIcolumn\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR]..."
 Lists the data in each record in \fItable\fR whose \fIcolumn\fR equals
@@ -636,16 +642,16 @@ alphabetical order by column name.
 The UUIDs shown for rows created in the same \fBovs\-vsctl\fR
 invocation will be wrong.
 .
-.IP "[\fB\-\-id=@\fIname\fR] [\fB\-\-if\-exists\fR] \fBget \fItable record \fR[\fIcolumn\fR[\fB:\fIkey\fR]]..."
+.IP "[\fB\-\-if\-exists\fR] [\fB\-\-id=@\fIname\fR] \fBget \fItable record \fR[\fIcolumn\fR[\fB:\fIkey\fR]]..."
 Prints the value of each specified \fIcolumn\fR in the given
 \fIrecord\fR in \fItable\fR.  For map columns, a \fIkey\fR may
 optionally be specified, in which case the value associated with
 \fIkey\fR in the column is printed, instead of the entire map.
 .IP
-For a map column, without \fB\-\-if\-exists\fR it is an error if
-\fIkey\fR does not exist; with it, a blank line is printed.  If
-\fIcolumn\fR is not a map column or if \fIkey\fR is not specified,
-\fB\-\-if\-exists\fR has no effect.
+Without \fB\-\-if\-exists\fR, it is an error if \fIrecord\fR does not
+exist or \fIkey\fR is specified, if \fIkey\fR does not exist in
+\fIrecord\fR.  With \fB\-\-if\-exists\fR, a missing \fIrecord\fR
+yields no output and a missing \fIkey\fR prints a blank line.
 .IP
 If \fB@\fIname\fR is specified, then the UUID for \fIrecord\fR may be
 referred to by that name later in the same \fBovs\-vsctl\fR
@@ -655,24 +661,34 @@ Both \fB\-\-id\fR and the \fIcolumn\fR arguments are optional, but
 usually at least one or the other should be specified.  If both are
 omitted, then \fBget\fR has no effect except to verify that
 \fIrecord\fR exists in \fItable\fR.
+.IP
+\fB\-\-id\fR and \fB\-\-if\-exists\fR cannot be used together.
 .
-.IP "\fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBset \fItable record column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
 Sets the value of each specified \fIcolumn\fR in the given
 \fIrecord\fR in \fItable\fR to \fIvalue\fR.  For map columns, a
 \fIkey\fR may optionally be specified, in which case the value
 associated with \fIkey\fR in that column is changed (or added, if none
 exists), instead of the entire map.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist.  With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
 .
-.IP "\fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBadd \fItable record column \fR[\fIkey\fB=\fR]\fIvalue\fR..."
 Adds the specified value or key-value pair to \fIcolumn\fR in
 \fIrecord\fR in \fItable\fR.  If \fIcolumn\fR is a map, then \fIkey\fR
 is required, otherwise it is prohibited.  If \fIkey\fR already exists
 in a map column, then the current \fIvalue\fR is not replaced (use the
 \fBset\fR command to replace an existing value).
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist.  With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
 .
-.IP "\fBremove \fItable record column \fR\fIvalue\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fR..."
-.IQ "\fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIvalue\fR..."
+.IQ "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIkey\fR..."
+.IQ "[\fB\-\-if\-exists\fR] \fBremove \fItable record column \fR\fIkey\fB=\fR\fIvalue\fR..."
 Removes the specified values or key-value pairs from \fIcolumn\fR in
 \fIrecord\fR in \fItable\fR.  The first form applies to columns that
 are not maps: each specified \fIvalue\fR is removed from the column.
@@ -683,11 +699,19 @@ pair is removed only if both key and value match.
 .IP
 It is not an error if the column does not contain the specified key or
 value or pair.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist.  With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
 .
-.IP "\fBclear\fR \fItable record column\fR..."
+.IP "[\fB\-\-if\-exists\fR] \fBclear\fR \fItable record column\fR..."
 Sets each \fIcolumn\fR in \fIrecord\fR in \fItable\fR to the empty set
 or empty map, as appropriate.  This command applies only to columns
 that are allowed to be empty.
+.IP
+Without \fB\-\-if-exists\fR, it is an error if \fIrecord\fR does not
+exist.  With \fB\-\-if-exists\fR, this command does nothing if
+\fIrecord\fR does not exist.
 .
 .IP "[\fB\-\-id=@\fIname\fR] \fBcreate\fR \fItable column\fR[\fB:\fIkey\fR]\fB=\fIvalue\fR..."
 Creates a new record in \fItable\fR and sets the initial values of
index bccb2c9..1ba8588 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <float.h>
@@ -298,7 +297,7 @@ parse_options(int argc, char *argv[], struct shash *local_options)
                 char *equals;
                 int has_arg;
 
-                assert(name[0] == '-' && name[1] == '-' && name[2]);
+                ovs_assert(name[0] == '-' && name[1] == '-' && name[2]);
                 name += 2;
 
                 equals = strchr(name, '=');
@@ -311,8 +310,8 @@ parse_options(int argc, char *argv[], struct shash *local_options)
 
                 o = find_option(name, options, n_options);
                 if (o) {
-                    assert(o - options >= n_global_long_options);
-                    assert(o->has_arg == has_arg);
+                    ovs_assert(o - options >= n_global_long_options);
+                    ovs_assert(o->has_arg == has_arg);
                 } else {
                     o = add_option(&options, &n_options, &allocated_options);
                     o->name = xstrdup(name);
@@ -845,8 +844,8 @@ ovs_delete_bridge(const struct ovsrec_open_vswitch *ovs,
 static void
 del_cached_bridge(struct vsctl_context *ctx, struct vsctl_bridge *br)
 {
-    assert(list_is_empty(&br->ports));
-    assert(hmap_is_empty(&br->children));
+    ovs_assert(list_is_empty(&br->ports));
+    ovs_assert(hmap_is_empty(&br->children));
     if (br->parent) {
         hmap_remove(&br->parent->children, &br->children_node);
     }
@@ -912,7 +911,7 @@ add_port_to_cache(struct vsctl_context *ctx, struct vsctl_bridge *parent,
 static void
 del_cached_port(struct vsctl_context *ctx, struct vsctl_port *port)
 {
-    assert(list_is_empty(&port->ifaces));
+    ovs_assert(list_is_empty(&port->ifaces));
     list_remove(&port->ports_node);
     shash_find_and_delete(&ctx->ports, port->port_cfg->name);
     ovsrec_port_delete(port->port_cfg);
@@ -1133,7 +1132,7 @@ find_bridge(struct vsctl_context *ctx, const char *name, bool must_exist)
 {
     struct vsctl_bridge *br;
 
-    assert(ctx->cache_valid);
+    ovs_assert(ctx->cache_valid);
 
     br = shash_find_data(&ctx->bridges, name);
     if (must_exist && !br) {
@@ -1158,7 +1157,7 @@ find_port(struct vsctl_context *ctx, const char *name, bool must_exist)
 {
     struct vsctl_port *port;
 
-    assert(ctx->cache_valid);
+    ovs_assert(ctx->cache_valid);
 
     port = shash_find_data(&ctx->ports, name);
     if (port && !strcmp(name, port->bridge->name)) {
@@ -1176,7 +1175,7 @@ find_iface(struct vsctl_context *ctx, const char *name, bool must_exist)
 {
     struct vsctl_iface *iface;
 
-    assert(ctx->cache_valid);
+    ovs_assert(ctx->cache_valid);
 
     iface = shash_find_data(&ctx->ifaces, name);
     if (iface && !strcmp(name, iface->port->bridge->name)) {
@@ -2646,7 +2645,8 @@ get_row_by_id(struct vsctl_context *ctx, const struct vsctl_table_class *table,
 
 static const struct ovsdb_idl_row *
 get_row (struct vsctl_context *ctx,
-         const struct vsctl_table_class *table, const char *record_id)
+         const struct vsctl_table_class *table, const char *record_id,
+         bool must_exist)
 {
     const struct ovsdb_idl_row *row;
     struct uuid uuid;
@@ -2663,15 +2663,7 @@ get_row (struct vsctl_context *ctx,
             }
         }
     }
-    return row;
-}
-
-static const struct ovsdb_idl_row *
-must_get_row(struct vsctl_context *ctx,
-             const struct vsctl_table_class *table, const char *record_id)
-{
-    const struct ovsdb_idl_row *row = get_row(ctx, table, record_id);
-    if (!row) {
+    if (must_exist && !row) {
         vsctl_fatal("no row \"%s\" in table %s",
                     record_id, table->class->name);
     }
@@ -2794,7 +2786,7 @@ parse_column_key_value(const char *arg,
     char *column_name;
     char *error;
 
-    assert(!(operatorp && !valuep));
+    ovs_assert(!(operatorp && !valuep));
     *keyp = NULL;
     if (valuep) {
         *valuep = NULL;
@@ -2943,7 +2935,7 @@ static void
 cmd_get(struct vsctl_context *ctx)
 {
     const char *id = shash_find_data(&ctx->options, "--id");
-    bool if_exists = shash_find(&ctx->options, "--if-exists");
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const char *table_name = ctx->argv[1];
     const char *record_id = ctx->argv[2];
     const struct vsctl_table_class *table;
@@ -2951,8 +2943,16 @@ cmd_get(struct vsctl_context *ctx)
     struct ds *out = &ctx->output;
     int i;
 
+    if (id && !must_exist) {
+        vsctl_fatal("--if-exists and --id may not be specified together");
+    }
+
     table = get_table(table_name);
-    row = must_get_row(ctx, table, record_id);
+    row = get_row(ctx, table, record_id, must_exist);
+    if (!row) {
+        return;
+    }
+
     if (id) {
         struct ovsdb_symbol *symbol;
         bool new;
@@ -3004,7 +3004,7 @@ cmd_get(struct vsctl_context *ctx)
             idx = ovsdb_datum_find_key(datum, &key,
                                        column->type.key.type);
             if (idx == UINT_MAX) {
-                if (!if_exists) {
+                if (must_exist) {
                     vsctl_fatal("no key \"%s\" in %s record \"%s\" column %s",
                                 key_string, table->class->name, record_id,
                                 column->name);
@@ -3130,6 +3130,10 @@ list_record(const struct ovsdb_idl_row *row,
 {
     size_t i;
 
+    if (!row) {
+        return;
+    }
+
     table_add_row(out);
     for (i = 0; i < n_columns; i++) {
         const struct ovsdb_idl_column *column = columns[i];
@@ -3160,6 +3164,7 @@ static void
 cmd_list(struct vsctl_context *ctx)
 {
     const char *column_names = shash_find_data(&ctx->options, "--columns");
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const struct ovsdb_idl_column **columns;
     const char *table_name = ctx->argv[1];
     const struct vsctl_table_class *table;
@@ -3172,7 +3177,7 @@ cmd_list(struct vsctl_context *ctx)
     out = ctx->table = list_make_table(columns, n_columns);
     if (ctx->argc > 2) {
         for (i = 2; i < ctx->argc; i++) {
-            list_record(must_get_row(ctx, table, ctx->argv[i]),
+            list_record(get_row(ctx, table, ctx->argv[i], must_exist),
                         columns, n_columns, out);
         }
     } else {
@@ -3302,6 +3307,7 @@ set_column(const struct vsctl_table_class *table,
 static void
 cmd_set(struct vsctl_context *ctx)
 {
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const char *table_name = ctx->argv[1];
     const char *record_id = ctx->argv[2];
     const struct vsctl_table_class *table;
@@ -3309,7 +3315,11 @@ cmd_set(struct vsctl_context *ctx)
     int i;
 
     table = get_table(table_name);
-    row = must_get_row(ctx, table, record_id);
+    row = get_row(ctx, table, record_id, must_exist);
+    if (!row) {
+        return;
+    }
+
     for (i = 3; i < ctx->argc; i++) {
         set_column(table, row, ctx->argv[i], ctx->symtab);
     }
@@ -3333,6 +3343,7 @@ pre_cmd_add(struct vsctl_context *ctx)
 static void
 cmd_add(struct vsctl_context *ctx)
 {
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const char *table_name = ctx->argv[1];
     const char *record_id = ctx->argv[2];
     const char *column_name = ctx->argv[3];
@@ -3344,8 +3355,11 @@ cmd_add(struct vsctl_context *ctx)
     int i;
 
     table = get_table(table_name);
-    row = must_get_row(ctx, table, record_id);
     die_if_error(get_column(table, column_name, &column));
+    row = get_row(ctx, table, record_id, must_exist);
+    if (!row) {
+        return;
+    }
 
     type = &column->type;
     ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
@@ -3390,6 +3404,7 @@ pre_cmd_remove(struct vsctl_context *ctx)
 static void
 cmd_remove(struct vsctl_context *ctx)
 {
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const char *table_name = ctx->argv[1];
     const char *record_id = ctx->argv[2];
     const char *column_name = ctx->argv[3];
@@ -3401,8 +3416,11 @@ cmd_remove(struct vsctl_context *ctx)
     int i;
 
     table = get_table(table_name);
-    row = must_get_row(ctx, table, record_id);
     die_if_error(get_column(table, column_name, &column));
+    row = get_row(ctx, table, record_id, must_exist);
+    if (!row) {
+        return;
+    }
 
     type = &column->type;
     ovsdb_datum_clone(&old, ovsdb_idl_read(row, column), &column->type);
@@ -3457,6 +3475,7 @@ pre_cmd_clear(struct vsctl_context *ctx)
 static void
 cmd_clear(struct vsctl_context *ctx)
 {
+    bool must_exist = !shash_find(&ctx->options, "--if-exists");
     const char *table_name = ctx->argv[1];
     const char *record_id = ctx->argv[2];
     const struct vsctl_table_class *table;
@@ -3464,7 +3483,11 @@ cmd_clear(struct vsctl_context *ctx)
     int i;
 
     table = get_table(table_name);
-    row = must_get_row(ctx, table, record_id);
+    row = get_row(ctx, table, record_id, must_exist);
+    if (!row) {
+        return;
+    }
+
     for (i = 3; i < ctx->argc; i++) {
         const struct ovsdb_idl_column *column;
         const struct ovsdb_type *type;
@@ -3597,7 +3620,7 @@ cmd_destroy(struct vsctl_context *ctx)
         for (i = 2; i < ctx->argc; i++) {
             const struct ovsdb_idl_row *row;
 
-            row = (must_exist ? must_get_row : get_row)(ctx, table, ctx->argv[i]);
+            row = get_row(ctx, table, ctx->argv[i], must_exist);
             if (row) {
                 ovsdb_idl_txn_delete(row);
             }
@@ -3778,7 +3801,7 @@ cmd_wait_until(struct vsctl_context *ctx)
 
     table = get_table(table_name);
 
-    row = get_row(ctx, table, record_id);
+    row = get_row(ctx, table, record_id, false);
     if (!row) {
         ctx->try_again = true;
         return;
@@ -3874,8 +3897,8 @@ run_prerequisites(struct vsctl_command *commands, size_t n_commands,
             (c->syntax->prerequisites)(&ctx);
             vsctl_context_done(&ctx, c);
 
-            assert(!c->output.string);
-            assert(!c->table);
+            ovs_assert(!c->output.string);
+            ovs_assert(!c->table);
         }
     }
 }
@@ -4126,12 +4149,14 @@ static const struct vsctl_command_syntax all_commands[] = {
     /* Database commands. */
     {"comment", 0, INT_MAX, NULL, NULL, NULL, "", RO},
     {"get", 2, INT_MAX, pre_cmd_get, cmd_get, NULL, "--if-exists,--id=", RO},
-    {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL, "--columns=", RO},
+    {"list", 1, INT_MAX, pre_cmd_list, cmd_list, NULL,
+     "--if-exists,--columns=", RO},
     {"find", 1, INT_MAX, pre_cmd_find, cmd_find, NULL, "--columns=", RO},
-    {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "", RW},
-    {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "", RW},
-    {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "", RW},
-    {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "", RW},
+    {"set", 3, INT_MAX, pre_cmd_set, cmd_set, NULL, "--if-exists", RW},
+    {"add", 4, INT_MAX, pre_cmd_add, cmd_add, NULL, "--if-exists", RW},
+    {"remove", 4, INT_MAX, pre_cmd_remove, cmd_remove, NULL, "--if-exists",
+     RW},
+    {"clear", 3, INT_MAX, pre_cmd_clear, cmd_clear, NULL, "--if-exists", RW},
     {"create", 2, INT_MAX, pre_create, cmd_create, post_create, "--id=", RW},
     {"destroy", 1, INT_MAX, pre_cmd_destroy, cmd_destroy, NULL,
      "--if-exists,--all", RW},
index 348faef..dd3099f 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <config.h>
 #include "bridge.h"
-#include <assert.h>
 #include <errno.h>
 #include <inttypes.h>
 #include <stdlib.h>
@@ -471,7 +470,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
 
     COVERAGE_INC(bridge_reconfigure);
 
-    assert(!reconfiguring);
+    ovs_assert(!reconfiguring);
     reconfiguring = true;
 
     /* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according
@@ -565,7 +564,7 @@ bridge_reconfigure_continue(const struct ovsrec_open_vswitch *ovs_cfg)
     struct bridge *br;
     bool done;
 
-    assert(reconfiguring);
+    ovs_assert(reconfiguring);
     done = bridge_reconfigure_ofp();
 
     /* Complete the configuration. */
@@ -1188,7 +1187,7 @@ iface_set_ofp_port(struct iface *iface, int ofp_port)
 {
     struct bridge *br = iface->port->bridge;
 
-    assert(iface->ofp_port < 0 && ofp_port >= 0);
+    ovs_assert(iface->ofp_port < 0 && ofp_port >= 0);
     iface->ofp_port = ofp_port;
     hmap_insert(&br->ifaces, &iface->ofp_port_node, hash_int(ofp_port, 0));
     iface_set_ofport(iface->cfg, ofp_port);
@@ -1402,7 +1401,7 @@ iface_create(struct bridge *br, struct if_cfg *if_cfg, int ofp_port)
      * internal datastructures may not be consistent.  Eventually, when port
      * additions and deletions are cheaper, these calls should be removed. */
     bridge_run_fast();
-    assert(!iface_lookup(br, iface_cfg->name));
+    ovs_assert(!iface_lookup(br, iface_cfg->name));
     error = iface_do_create(br, if_cfg, &ofp_port, &netdev);
     bridge_run_fast();
     if (error) {
@@ -1841,7 +1840,7 @@ iface_refresh_stats(struct iface *iface)
 #define IFACE_STAT(MEMBER, NAME) values[i++] = stats.MEMBER;
     IFACE_STATS;
 #undef IFACE_STAT
-    assert(i == ARRAY_SIZE(keys));
+    ovs_assert(i == ARRAY_SIZE(keys));
 
     ovsrec_interface_set_statistics(iface->cfg, keys, values,
                                     ARRAY_SIZE(keys));
@@ -2403,7 +2402,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg)
 {
     struct bridge *br;
 
-    assert(!bridge_lookup(br_cfg->name));
+    ovs_assert(!bridge_lookup(br_cfg->name));
     br = xzalloc(sizeof *br);
 
     br->name = xstrdup(br_cfg->name);
@@ -2569,7 +2568,7 @@ bridge_add_del_ports(struct bridge *br,
     struct shash new_ports;
     size_t i;
 
-    assert(hmap_is_empty(&br->if_cfg_todo));
+    ovs_assert(hmap_is_empty(&br->if_cfg_todo));
 
     /* Collect new ports. */
     shash_init(&new_ports);
@@ -2730,12 +2729,23 @@ bridge_configure_local_iface_netdev(struct bridge *br,
 
 /* Returns true if 'a' and 'b' are the same except that any number of slashes
  * in either string are treated as equal to any number of slashes in the other,
- * e.g. "x///y" is equal to "x/y". */
+ * e.g. "x///y" is equal to "x/y".
+ *
+ * Also, if 'b_stoplen' bytes from 'b' are found to be equal to corresponding
+ * bytes from 'a', the function considers this success.  Specify 'b_stoplen' as
+ * SIZE_MAX to compare all of 'a' to all of 'b' rather than just a prefix of
+ * 'b' against a prefix of 'a'.
+ */
 static bool
-equal_pathnames(const char *a, const char *b)
+equal_pathnames(const char *a, const char *b, size_t b_stoplen)
 {
-    while (*a == *b) {
-        if (*a == '/') {
+    const char *b_start = b;
+    for (;;) {
+        if (b - b_start >= b_stoplen) {
+            return true;
+        } else if (*a != *b) {
+            return false;
+        } else if (*a == '/') {
             a += strspn(a, "/");
             b += strspn(b, "/");
         } else if (*a == '\0') {
@@ -2745,7 +2755,6 @@ equal_pathnames(const char *a, const char *b)
             b++;
         }
     }
-    return false;
 }
 
 static void
@@ -2792,21 +2801,40 @@ bridge_configure_remotes(struct bridge *br,
             static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
             char *whitelist;
 
-            whitelist = xasprintf("unix:%s/%s.controller",
+            if (!strncmp(c->target, "unix:", 5)) {
+                /* Connect to a listening socket */
+                whitelist = xasprintf("unix:%s/", ovs_rundir());
+                if (!equal_pathnames(c->target, whitelist,
+                                     strlen(whitelist))) {
+                    VLOG_ERR_RL(&rl, "bridge %s: Not connecting to socket "
+                                  "controller \"%s\" due to possibility for "
+                                  "remote exploit.  Instead, specify socket "
+                                  "in whitelisted \"%s\" or connect to "
+                                  "\"unix:%s/%s.mgmt\" (which is always "
+                                  "available without special configuration).",
+                                  br->name, c->target, whitelist,
                                   ovs_rundir(), br->name);
-            if (!equal_pathnames(c->target, whitelist)) {
-                /* Prevent remote ovsdb-server users from accessing arbitrary
-                 * Unix domain sockets and overwriting arbitrary local
-                 * files. */
-                VLOG_ERR_RL(&rl, "bridge %s: Not adding Unix domain socket "
-                            "controller \"%s\" due to possibility for remote "
-                            "exploit.  Instead, specify whitelisted \"%s\" or "
-                            "connect to \"unix:%s/%s.mgmt\" (which is always "
-                            "available without special configuration).",
-                            br->name, c->target, whitelist,
-                            ovs_rundir(), br->name);
-                free(whitelist);
-                continue;
+                    free(whitelist);
+                    continue;
+                }
+            } else {
+               whitelist = xasprintf("punix:%s/%s.controller",
+                                     ovs_rundir(), br->name);
+               if (!equal_pathnames(c->target, whitelist, SIZE_MAX)) {
+                   /* Prevent remote ovsdb-server users from accessing
+                    * arbitrary Unix domain sockets and overwriting arbitrary
+                    * local files. */
+                   VLOG_ERR_RL(&rl, "bridge %s: Not adding Unix domain socket "
+                                  "controller \"%s\" due to possibility of "
+                                  "overwriting local files. Instead, specify "
+                                  "whitelisted \"%s\" or connect to "
+                                  "\"unix:%s/%s.mgmt\" (which is always "
+                                  "available without special configuration).",
+                                  br->name, c->target, whitelist,
+                                  ovs_rundir(), br->name);
+                   free(whitelist);
+                   continue;
+               }
             }
 
             free(whitelist);
index 84e5ad1..9736b79 100644 (file)
@@ -15,7 +15,6 @@
 
 #include <config.h>
 
-#include <assert.h>
 #include <errno.h>
 #include <getopt.h>
 #include <limits.h>
index 90446f2..f679516 100644 (file)
@@ -17,7 +17,6 @@
 
 #include "system-stats.h"
 
-#include <assert.h>
 #include <ctype.h>
 #include <dirent.h>
 #include <errno.h>
@@ -169,7 +168,7 @@ get_boot_time(void)
     static long long int cache_expiration = LLONG_MIN;
     static long long int boot_time;
 
-    assert(LINUX_DATAPATH);
+    ovs_assert(LINUX_DATAPATH);
 
     if (time_msec() >= cache_expiration) {
         static const char stat_file[] = "/proc/stat";
@@ -201,7 +200,7 @@ get_boot_time(void)
 static unsigned long long int
 ticks_to_ms(unsigned long long int ticks)
 {
-    assert(LINUX_DATAPATH);
+    ovs_assert(LINUX_DATAPATH);
 
 #ifndef USER_HZ
 #define USER_HZ 100
@@ -234,7 +233,7 @@ get_raw_process_info(pid_t pid, struct raw_process_info *raw)
     FILE *stream;
     int n;
 
-    assert(LINUX_DATAPATH);
+    ovs_assert(LINUX_DATAPATH);
 
     sprintf(file_name, "/proc/%lu/stat", (unsigned long int) pid);
     stream = fopen(file_name, "r");
@@ -319,7 +318,7 @@ count_crashes(pid_t pid)
     int crashes = 0;
     FILE *stream;
 
-    assert(LINUX_DATAPATH);
+    ovs_assert(LINUX_DATAPATH);
 
     sprintf(file_name, "/proc/%lu/cmdline", (unsigned long int) pid);
     stream = fopen(file_name, "r");
@@ -362,7 +361,7 @@ get_process_info(pid_t pid, struct process_info *pinfo)
 {
     struct raw_process_info child;
 
-    assert(LINUX_DATAPATH);
+    ovs_assert(LINUX_DATAPATH);
     if (!get_raw_process_info(pid, &child)) {
         return false;
     }
@@ -640,7 +639,7 @@ system_stats_reply_cb(struct ofpbuf *reply,
     smap_init(received_stats);
     smap_from_json(received_stats, json);
 
-    assert(state == S_REQUEST_SENT);
+    ovs_assert(state == S_REQUEST_SENT);
     state = S_REPLY_RECEIVED;
 
     json_destroy(json);