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
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
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.
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
-----
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)
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).
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
- 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.
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)
#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)
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) {
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)
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);
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:
#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:
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;
};
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;
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)
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;
.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,
{
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;
* 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);
struct sk_buff *reply;
struct datapath *dp;
struct flow_table *table;
+ struct sw_flow_actions *acts = NULL;
int error;
int key_len;
/* 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;
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)) {
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. */
} 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
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);
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;
}
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;
}
[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),
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.
}
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. */
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;
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:
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;
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 {
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 *,
/* 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,
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 */
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,
/* 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).
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)
goto error;
}
- if (unlikely(skb_warn_if_lro(skb)))
- goto error;
-
skb->dev = netdev_vport->dev;
forward_ip_summed(skb, true);
- 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.
#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
-
-
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.
__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
/*
- * 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.
#include "aes128.h"
-#include <assert.h>
-
#include "util.h"
static const uint32_t Te0[256] = {
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
}
- assert(rk == &aes->rk[40]);
+ ovs_assert(rk == &aes->rk[40]);
}
void
lib/hmap.h \
lib/hmapx.c \
lib/hmapx.h \
+ lib/jhash.c \
+ lib/jhash.h \
lib/json.c \
lib/json.h \
lib/jsonrpc.c \
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);
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)
-/* 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.
#include <config.h>
#include "byteq.h"
-#include <assert.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
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++;
}
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);
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;
if (n > 0) {
byteq_advance_tail(q, n);
} else {
- assert(n < 0);
+ ovs_assert(n < 0);
return errno;
}
}
void
byteq_advance_tail(struct byteq *q, unsigned int n)
{
- assert(byteq_tailroom(q) >= n);
+ ovs_assert(byteq_tailroom(q) >= n);
q->tail += n;
}
void
byteq_advance_head(struct byteq *q, unsigned int n)
{
- assert(byteq_headroom(q) >= n);
+ ovs_assert(byteq_headroom(q) >= n);
q->head += n;
}
#include <config.h>
#include "cfm.h"
-#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
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. */
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;
}
}
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);
#include <config.h>
#include "classifier.h"
-#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include "byte-order.h"
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
#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
#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
#include <config.h>
#include "daemon.h"
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
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;
}
#include "dpif-linux.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
*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;
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];
struct ofpbuf *request_buf;
int error;
- assert((reply != NULL) == (bufp != NULL));
+ ovs_assert((reply != NULL) == (bufp != NULL));
error = dpif_linux_init();
if (error) {
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);
}
/* 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);
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;
#include <config.h>
#include "dpif.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
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);
}
if (error) {
return error;
}
- assert(dp != NULL);
+ ovs_assert(dp != NULL);
}
} else {
if (dp->class != class) {
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);
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;
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) {
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);
* 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"
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
#include <config.h>
#include "dpif-provider.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
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++;
}
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);
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) {
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) {
#include <config.h>
#include "dynamic-string.h"
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
needed = vsnprintf(&ds->string[ds->length], available, format, args);
va_end(args);
- assert(needed < available);
+ ovs_assert(needed < available);
ds->length += needed;
}
}
*/
#include <config.h>
#include "fatal-signal.h"
-#include <assert.h>
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
{
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;
#include <config.h>
#include <sys/types.h>
#include "flow.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include "csum.h"
#include "dynamic-string.h"
#include "hash.h"
+#include "jhash.h"
#include "match.h"
#include "ofpbuf.h"
#include "openflow/openflow.h"
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;
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'. */
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);
}
}
- 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
}
}
- 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'
/*
- * 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'. */
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;
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);
}
/*
- * 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
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
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
#include <config.h>
#include "hmap.h"
-#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "coverage.h"
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) {
/*
- * 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.
#include "hmapx.h"
-#include <assert.h>
-
#include "hash.h"
static struct hmapx_node *
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'. */
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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 */
#include "json.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
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
}
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);
#include "jsonrpc.h"
-#include <assert.h>
#include <errno.h>
#include "byteq.h"
{
struct jsonrpc *rpc;
- assert(stream != NULL);
+ ovs_assert(stream != NULL);
rpc = xzalloc(sizeof *rpc);
rpc->name = xstrdup(stream_get_name(stream));
static void
jsonrpc_error(struct jsonrpc *rpc, int error)
{
- assert(error);
+ ovs_assert(error);
if (!rpc->status) {
rpc->status = error;
jsonrpc_cleanup(rpc);
-/* 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.
#include <config.h>
#include "lacp.h"
-#include <assert.h>
#include <stdlib.h>
#include "dynamic-string.h"
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);
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);
*/
#include <config.h>
#include "list.h"
-#include <assert.h>
/* Initializes 'list' as an empty list. */
void
{
struct list *list = CONST_CAST(struct list *, list_);
- assert(!list_is_empty(list));
+ ovs_assert(!list_is_empty(list));
return list->next;
}
{
struct list *list = CONST_CAST(struct list *, list_);
- assert(!list_is_empty(list));
+ ovs_assert(!list_is_empty(list));
return list->prev;
}
#include <config.h>
#include "mac-learning.h"
-#include <assert.h>
#include <inttypes.h>
#include <stdlib.h>
} 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);
#include <config.h>
#include "match.h"
-#include <assert.h>
#include <stdlib.h>
#include "byte-order.h"
#include "dynamic-string.h"
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;
}
/*
- * 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.
#include "meta-flow.h"
-#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <netinet/icmp6.h>
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];
}
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);
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))){
{
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) {
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;
{
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);
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();
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++) {
#include <config.h>
#include <stdlib.h>
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include "socket-util.h"
#include "shash.h"
#include "svec.h"
+#include "util.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(netdev_bsd);
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);
}
netdev_bsd_destroy,
NULL, /* get_config */
NULL, /* set_config */
+ NULL, /* get_tunnel_config */
netdev_bsd_open_system,
netdev_bsd_close,
netdev_bsd_destroy,
NULL, /* get_config */
NULL, /* set_config */
+ NULL, /* get_tunnel_config */
netdev_bsd_open_system,
netdev_bsd_close,
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);
}
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);
}
#include "netdev-linux.h"
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <arpa/inet.h>
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);
}
{
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);
}
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);
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;
}
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;
}
/* 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;
/* Generic interface to network devices. */
-#include <assert.h>
-
#include "netdev.h"
#include "list.h"
#include "shash.h"
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.
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);
}
#include <config.h>
#include "netdev.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <netinet/in.h>
if (error) {
return error;
}
- assert(netdev_dev->netdev_class == class);
+ ovs_assert(netdev_dev->netdev_class == class);
}
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);
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
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;
{
char *name = netdev_dev->name;
- assert(!netdev_dev->ref_cnt);
+ ovs_assert(!netdev_dev->ref_cnt);
shash_delete(&netdev_dev_shash, netdev_dev->node);
#include "netlink-notifier.h"
-#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
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);
}
#include <config.h>
#include "netlink-socket.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
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)",
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;
while (!dump->status) {
struct ofpbuf reply;
if (!nl_dump_next(dump, &reply)) {
- assert(dump->status);
+ ovs_assert(dump->status);
}
}
}
ofpbuf_delete(reply);
- assert(*number != 0);
+ ovs_assert(*number != 0);
}
return *number > 0 ? 0 : -*number;
}
#include <config.h>
#include "netlink.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
{
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);
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;
{
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;
{
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;
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;
}
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;
}
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;
}
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);
}
{
uint32_t header;
- assert((cookie != NULL) == (cookie_mask != NULL));
+ ovs_assert((cookie != NULL) == (cookie_mask != NULL));
match_init_catchall(match);
if (cookie) {
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,
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";
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);
}
}
-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
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;
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:
{
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;
}
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;
}
}
: 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'
}
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);
}
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;
}
}
/* 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);
* 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.
#include "nx-match.h"
#include "ofp-util.h"
#include "ofpbuf.h"
+#include "util.h"
#include "vlog.h"
VLOG_DEFINE_THIS_MODULE(ofp_actions);
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; \
} \
\
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;
}
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; \
} \
\
{
size_t ofs = error - OFPERR_OFS;
- assert(ofperr_is_valid(error));
+ ovs_assert(ofperr_is_valid(error));
return &domain->errors[ofs];
}
/*
- * 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.
#include <config.h>
#include "ofp-msgs.h"
-#include <assert.h>
#include "byte-order.h"
#include "dynamic-string.h"
#include "hash.h"
const struct ofp_header *oh, size_t length)
{
enum ofperr error = ofphdrs_decode(hdrs, oh, length);
- assert(!error);
+ ovs_assert(!error);
}
static bool
enum ofpraw raw;
error = ofpraw_pull(&raw, msg);
- assert(!error);
+ ovs_assert(!error);
return raw;
}
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);
}
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);
}
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
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:
}
error = ofpraw_from_ofphdrs(&reply_raw, &hdrs);
- assert(!error);
+ ovs_assert(!error);
return reply_raw;
}
{
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),
{
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];
}
/*
- * 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.
{
struct ds s;
- assert(!(protocols & ~OFPUTIL_P_ANY));
+ ovs_assert(!(protocols & ~OFPUTIL_P_ANY));
if (protocols == 0) {
return xstrdup("none");
}
return ofputil_make_flow_mod_table_id(want_tid);
}
- assert(current == want);
+ ovs_assert(current == want);
*next = current;
return NULL;
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);
ps->reason = ops->reason;
retval = ofputil_pull_phy_port(oh->version, &b, &ps->desc);
- assert(retval != EOF);
+ ovs_assert(retval != EOF);
return retval;
}
#ifndef OFP_UTIL_H
#define OFP_UTIL_H 1
-#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <config.h>
#include "ofpbuf.h"
-#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "dynamic-string.h"
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;
}
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;
}
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;
#include "ovsdb-data.h"
-#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <inttypes.h>
inited = true;
}
- assert(ovsdb_atomic_type_is_valid(type));
+ ovs_assert(ovsdb_atomic_type_is_valid(type));
return &default_atoms[type];
}
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) {
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) {
&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);
struct ovsdb_error *error;
a->n = n;
error = ovsdb_datum_sort(a, type->key.type);
- assert(!error);
+ ovs_assert(!error);
}
}
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; ) {
{
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;
#include "ovsdb-idl.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
if (idl) {
size_t i;
- assert(!idl->txn);
+ ovs_assert(!idl->txn);
ovsdb_idl_clear(idl);
jsonrpc_session_close(idl->session);
{
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;
{
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];
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;
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);
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];
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);
}
{
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;
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;
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;
}
{
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)) {
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"
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;
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);
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);
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;
}
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. */
#include <config.h>
#include "packets.h"
-#include <assert.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
/*
- * 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.
#include <config.h>
#include "pcap.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <string.h>
{
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) {
#include <config.h>
#include "poll-loop.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <poll.h>
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;
#include <config.h>
#include "process.h"
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
struct process *p;
const char *slash;
- assert(sigchld_is_blocked());
+ ovs_assert(sigchld_is_blocked());
p = xzalloc(sizeof *p);
p->pid = pid;
int
process_status(const struct process *p)
{
- assert(p->exited);
+ ovs_assert(p->exited);
return p->status;
}
#include <config.h>
#include "random.h"
-#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
void
random_set_seed(uint32_t seed_)
{
- assert(seed_);
+ ovs_assert(seed_);
seed = seed_;
}
#include <config.h>
#include "rconn.h"
-#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
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;
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
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);
}
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);
}
#include <config.h>
#include "reconnect.h"
-#include <assert.h>
#include <stdlib.h>
#include "poll-loop.h"
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:
#include "route-table.h"
-#include <assert.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <linux/rtnetlink.h>
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);
#ifndef SAT_MATH_H
#define SAT_MATH_H 1
-#include <assert.h>
#include <limits.h>
/* Saturating addition: overflow yields UINT_MAX. */
#include <config.h>
#include "shash.h"
-#include <assert.h>
#include "hash.h"
static struct shash_node *shash_find__(const struct shash *,
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
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;
}
SHASH_FOR_EACH (node, sh) {
nodes[i++] = node;
}
- assert(i == n);
+ ovs_assert(i == n);
qsort(nodes, n, sizeof *nodes, compare_nodes_by_name);
#include <config.h>
#include "signals.h"
-#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
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);
#include <config.h>
#include "simap.h"
-#include <assert.h>
#include "hash.h"
static size_t hash_name(const char *, size_t length);
SIMAP_FOR_EACH (node, simap) {
nodes[i++] = node;
}
- assert(i == n);
+ ovs_assert(i == n);
qsort(nodes, n, sizeof *nodes, compare_nodes_by_name);
#include <config.h>
#include "smap.h"
-#include <assert.h>
-
#include "hash.h"
#include "json.h"
SMAP_FOR_EACH (node, smap) {
nodes[i++] = node;
}
- assert(i == n);
+ ovs_assert(i == n);
qsort(nodes, n, sizeof *nodes, compare_nodes_by_key);
#include <config.h>
#include "socket-util.h"
#include <arpa/inet.h>
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
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;
} 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);
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);
/*
- * 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.
#include "sset.h"
-#include <assert.h>
-
#include "hash.h"
static uint32_t
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'. */
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
#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"
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];
}
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;
}
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;
#include <config.h>
#include "stream-fd.h"
-#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
/*
- * 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.
#ifndef STREAM_PROVIDER_H
#define STREAM_PROVIDER_H 1
-#include <assert.h>
#include <sys/types.h>
#include "stream.h"
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 {
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 {
#include <config.h>
#include "stream-ssl.h"
#include "dhparams.h"
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
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);
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;
}
#include <config.h>
#include "stream.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
#include <config.h>
#include "stream-provider.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <netinet/in.h>
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. */
}
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. */
}
stream_connect_wait(stream);
poll_block();
}
- assert(error != EINPROGRESS);
+ ovs_assert(error != EINPROGRESS);
}
if (error) {
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) {
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:
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;
}
: 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
/*
- * 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.
#include <config.h>
#include "svec.h"
-#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
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 . */
{
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);
}
{
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;
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++) {
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]);
}
#include "table.h"
-#include <assert.h>
-
#include "dynamic-string.h"
#include "json.h"
#include "ovsdb-data.h"
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);
{
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;
/*
- * 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.
#ifndef TAG_H
#define TAG_H 1
-#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include "util.h"
#include <config.h>
#include "timeval.h"
-#include <assert.h>
#include <errno.h>
#if HAVE_EXECINFO_H
#include <execinfo.h>
{
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);
#include <config.h>
#include "unixctl.h"
-#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include "coverage.h"
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;
struct jsonrpc_msg *reply;
COVERAGE_INC(unixctl_replied);
- assert(conn->request_id);
+ ovs_assert(conn->request_id);
if (!body) {
body = "";
/*
- * 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.
#include <config.h>
#include "util.h"
-#include <assert.h>
#include <errno.h>
#include <limits.h>
#include <stdarg.h>
/* --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)
{
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."
#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.
*
/* 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. */
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 {
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 {
/*
- * 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.
*/
#include <config.h>
-#include <assert.h>
#include <errno.h>
#include <poll.h>
#include <stdlib.h>
#include <config.h>
#include "vconn-provider.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <netinet/in.h>
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. */
}
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. */
}
}
/* Success. */
- assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
+ ovs_assert(vconn->state != VCS_CONNECTING || vconn->class->connect);
*vconnp = vconn;
return 0;
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) {
{
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()) {
vconn_connect_wait(vconn);
poll_block();
}
- assert(error != EINPROGRESS);
+ ovs_assert(error != EINPROGRESS);
return error;
}
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:
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;
}
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
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,
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. */
{
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)) {
#include "ofproto-dpif-governor.h"
-#include <assert.h>
#include <stdlib.h>
#include "coverage.h"
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;
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) {
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;
}
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);
}
{
struct shash_node *node;
- assert(backer->refcount > 0);
+ ovs_assert(backer->refcount > 0);
if (--backer->refcount) {
return;
if (error) {
VLOG_ERR("failed to open datapath of type %s: %s", type,
strerror(error));
+ free(backer);
return error;
}
}
*rulep = rule_dpif_lookup__(ofproto, &fm.match.flow, TBL_INTERNAL);
- assert(*rulep != NULL);
+ ovs_assert(*rulep != NULL);
return 0;
}
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) {
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);
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++) {
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++) {
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) {
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);
{
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;
}
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);
}
}
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);
/* 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);
/* 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;
}
/*
- * 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");
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);
{
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);
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;
}
{
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);
{
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);
void
ofproto_rule_destroy(struct rule *rule)
{
- assert(!rule->pending);
+ ovs_assert(!rule->pending);
oftable_remove_rule(rule);
ofproto_rule_destroy__(rule);
}
{
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);
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.) */
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;
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");
}
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];
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);
&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;
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;
}
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);
}
}
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;
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) {
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;
break;
case OFOPERATION_DELETE:
- assert(!op->error);
+ ovs_assert(!op->error);
ofproto_rule_destroy__(rule);
op->rule = NULL;
break;
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);
}
struct ofproto *ofproto = group->ofproto;
struct ofoperation *op;
- assert(!rule->pending);
+ ovs_assert(!rule->pending);
op = rule->pending = xzalloc(sizeof *op);
op->group = group;
{
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)) {
struct rule *
ofoperation_get_victim(struct ofoperation *op)
{
- assert(op->type == OFOPERATION_ADD);
+ ovs_assert(op->type == OFOPERATION_ADD);
return op->victim;
}
\f
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);
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) {
#include <config.h>
-#include <assert.h>
#include <limits.h>
#include "column.h"
op_name);
}
} else {
- assert(ovsdb_parser_has_error(&parser));
+ ovs_assert(ovsdb_parser_has_error(&parser));
}
/* A parse error overrides any other error.
#include "file.h"
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
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) {
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,
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
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);
}
#include "jsonrpc-server.h"
-#include <assert.h>
#include <errno.h>
#include "bitmap.h"
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);
}
#include "log.h"
-#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
*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;
}
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;
}
#include <config.h>
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#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"). */
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
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())
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
{
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
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(),
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 = ''
%(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(),
{
struct ovsdb_datum datum;
- assert(inited);
+ ovs_assert(inited);
if (smap) {
struct smap_node *node;
size_t i;
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)
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);"
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:
#include <config.h>
-#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <signal.h>
#include "row.h"
-#include <assert.h>
#include <stddef.h>
#include "dynamic-string.h"
{
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;
#include "server.h"
-#include <assert.h>
-
#include "hash.h"
#include "ovsdb.h"
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);
}
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);
-/* 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.
#include "table.h"
-#include <assert.h>
#include <limits.h>
#include "json.h"
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);
}
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;
#include "transaction.h"
-#include <assert.h>
-
#include "bitmap.h"
#include "dynamic-string.h"
#include "hash.h"
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);
}
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;
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;
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 {
{
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]);
#include "trigger.h"
-#include <assert.h>
#include <limits.h>
#include "json.h"
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);
}
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):
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
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
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.'
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
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`
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
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
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])
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
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
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
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
[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)'
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])
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])
[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
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])
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])
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])
#include <stdlib.h>
#include <string.h>
#include "hash.h"
+#include "jhash.h"
#undef NDEBUG
#include <assert.h>
}
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
* 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
* 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;
}
#include <config.h>
+#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include "command-line.h"
#include "random.h"
#include "util.h"
+#include "vlog.h"
#undef NDEBUG
#include <assert.h>
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},
{"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;
}
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 () {
> "${script_interfaces}"
}
+restore_ofports () {
+ [ -n "${script_ofports}" ] && \
+ action "Restoring ofport values" "${script_ofports}"
+}
+
restore_flows () {
[ -n "${script_flows}" ] && \
action "Restoring saved flows" "${script_flows}"
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
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
#include <config.h>
#include <arpa/inet.h>
-#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
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);
}
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);
break;
}
}
- assert(IS_POW2(protocol));
+ ovs_assert(IS_POW2(protocol));
printf("chosen protocol: %s\n", ofputil_protocol_to_string(protocol));
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
}
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
save_interfaces "$@"
exit 0
;;
+ "save-ofports")
+ shift
+ save_ofports "$@"
+ exit 0
+ ;;
-h | --help)
usage
exit 0
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
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
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.
.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
/*
- * 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.
#include <config.h>
-#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <float.h>
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, '=');
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);
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);
}
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);
{
struct vsctl_bridge *br;
- assert(ctx->cache_valid);
+ ovs_assert(ctx->cache_valid);
br = shash_find_data(&ctx->bridges, name);
if (must_exist && !br) {
{
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)) {
{
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)) {
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;
}
}
}
- 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);
}
char *column_name;
char *error;
- assert(!(operatorp && !valuep));
+ ovs_assert(!(operatorp && !valuep));
*keyp = NULL;
if (valuep) {
*valuep = NULL;
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;
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;
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);
{
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];
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;
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 {
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;
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);
}
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];
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);
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];
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);
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;
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;
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);
}
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;
(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);
}
}
}
/* 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},
#include <config.h>
#include "bridge.h"
-#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
COVERAGE_INC(bridge_reconfigure);
- assert(!reconfiguring);
+ ovs_assert(!reconfiguring);
reconfiguring = true;
/* Destroy "struct bridge"s, "struct port"s, and "struct iface"s according
struct bridge *br;
bool done;
- assert(reconfiguring);
+ ovs_assert(reconfiguring);
done = bridge_reconfigure_ofp();
/* Complete the configuration. */
{
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);
* 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) {
#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));
{
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);
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);
/* 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') {
b++;
}
}
- return false;
}
static void
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);
#include <config.h>
-#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include "system-stats.h"
-#include <assert.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
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";
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
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");
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");
{
struct raw_process_info child;
- assert(LINUX_DATAPATH);
+ ovs_assert(LINUX_DATAPATH);
if (!get_raw_process_info(pid, &child)) {
return false;
}
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);