#include "unixctl.h"
#include "util.h"
#include "vconn.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
#include "meta-flow.h"
#include "sort.h"
static const struct command *get_all_commands(void);
-NO_RETURN static void usage(void);
+OVS_NO_RETURN static void usage(void);
static void parse_options(int argc, char *argv[]);
static bool recv_flow_stats_reply(struct vconn *, ovs_be32 send_xid,
" add-groups SWITCH FILE add group from FILE\n"
" mod-group SWITCH GROUP modify specific group\n"
" del-groups SWITCH [GROUP] delete matching GROUPs\n"
+ " insert-buckets SWITCH [GROUP] add buckets to GROUP\n"
+ " remove-buckets SWITCH [GROUP] remove buckets from GROUP\n"
" dump-group-features SWITCH print group features\n"
" dump-groups SWITCH [GROUP] print group description\n"
" dump-group-stats SWITCH [GROUP] print group statistics\n"
}
static void run(int retval, const char *message, ...)
- PRINTF_FORMAT(2, 3);
+ OVS_PRINTF_FORMAT(2, 3);
static void
run(int retval, const char *message, ...)
*
* Destroys all of the 'requests'. */
static void
-transact_multiple_noreply(struct vconn *vconn, struct list *requests)
+transact_multiple_noreply(struct vconn *vconn, struct ovs_list *requests)
{
struct ofpbuf *request, *reply;
static void
transact_noreply(struct vconn *vconn, struct ofpbuf *request)
{
- struct list requests;
+ struct ovs_list requests;
list_init(&requests);
list_push_back(&requests, &request->list_node);
ofctl_group_mod(argc, argv, OFPGC11_DELETE);
}
+static void
+ofctl_insert_bucket(int argc, char *argv[])
+{
+ ofctl_group_mod(argc, argv, OFPGC15_INSERT_BUCKET);
+}
+
+static void
+ofctl_remove_bucket(int argc, char *argv[])
+{
+ ofctl_group_mod(argc, argv, OFPGC15_REMOVE_BUCKET);
+}
+
static void
ofctl_dump_group_stats(int argc, char *argv[])
{
ovs_be64 cookie;
uint16_t idle_timeout;
uint16_t hard_timeout;
+ uint16_t importance;
uint16_t flags;
struct ofpact *ofpacts;
size_t ofpacts_len;
return (a->cookie == b->cookie
&& a->idle_timeout == b->idle_timeout
&& a->hard_timeout == b->hard_timeout
+ && a->importance == b->importance
&& ofpacts_equal(a->ofpacts, a->ofpacts_len,
b->ofpacts, b->ofpacts_len));
}
if (version->hard_timeout != OFP_FLOW_PERMANENT) {
ds_put_format(s, " hard_timeout=%"PRIu16, version->hard_timeout);
}
+ if (version->importance != 0) {
+ ds_put_format(s, " importance=%"PRIu16, version->importance);
+ }
ds_put_cstr(s, " actions=");
ofpacts_format(version->ofpacts, version->ofpacts_len, s);
{
struct fte *fte;
- CLS_FOR_EACH_SAFE (fte, rule, cls) {
+ classifier_defer(cls);
+ CLS_FOR_EACH (fte, rule, cls) {
classifier_remove(cls, &fte->rule);
- fte_free(fte);
+ ovsrcu_postpone(fte_free, fte);
}
classifier_destroy(cls);
}
old = fte_from_cls_rule(classifier_replace(cls, &fte->rule));
if (old) {
- fte_version_free(old->versions[index]);
fte->versions[!index] = old->versions[!index];
- cls_rule_destroy(&old->rule);
- free(old);
+ old->versions[!index] = NULL;
+
+ ovsrcu_postpone(fte_free, old);
}
}
ds_init(&s);
usable_protocols = OFPUTIL_P_ANY;
line_number = 0;
+ classifier_defer(cls);
while (!ds_get_preprocessed_line(&s, file, &line_number)) {
struct fte_version *version;
struct ofputil_flow_mod fm;
version->cookie = fm.new_cookie;
version->idle_timeout = fm.idle_timeout;
version->hard_timeout = fm.hard_timeout;
+ version->importance = fm.importance;
version->flags = fm.flags & (OFPUTIL_FF_SEND_FLOW_REM
| OFPUTIL_FF_EMERG);
version->ofpacts = fm.ofpacts;
fte_insert(cls, &fm.match, fm.priority, version, index);
}
+ classifier_publish(cls);
ds_destroy(&s);
if (file != stdin) {
reply = NULL;
ofpbuf_init(&ofpacts, 0);
+ classifier_defer(cls);
while (recv_flow_stats_reply(vconn, send_xid, &reply, &fs, &ofpacts)) {
struct fte_version *version;
version->cookie = fs.cookie;
version->idle_timeout = fs.idle_timeout;
version->hard_timeout = fs.hard_timeout;
+ version->importance = fs.importance;
version->flags = 0;
version->ofpacts_len = fs.ofpacts_len;
version->ofpacts = xmemdup(fs.ofpacts, fs.ofpacts_len);
fte_insert(cls, &fs.match, fs.priority, version, index);
}
+ classifier_publish(cls);
ofpbuf_uninit(&ofpacts);
}
static void
fte_make_flow_mod(const struct fte *fte, int index, uint16_t command,
- enum ofputil_protocol protocol, struct list *packets)
+ enum ofputil_protocol protocol, struct ovs_list *packets)
{
const struct fte_version *version = fte->versions[index];
struct ofputil_flow_mod fm;
fm.command = command;
fm.idle_timeout = version->idle_timeout;
fm.hard_timeout = version->hard_timeout;
+ fm.importance = version->importance;
fm.buffer_id = UINT32_MAX;
fm.out_port = OFPP_ANY;
fm.flags = version->flags;
enum { FILE_IDX = 0, SWITCH_IDX = 1 };
enum ofputil_protocol usable_protocols, protocol;
struct classifier cls;
- struct list requests;
+ struct ovs_list requests;
struct vconn *vconn;
struct fte *fte;
1, 2, ofctl_mod_group },
{ "del-groups", "switch [group]",
1, 2, ofctl_del_groups },
+ { "insert-buckets", "switch [group]",
+ 1, 2, ofctl_insert_bucket },
+ { "remove-buckets", "switch [group]",
+ 1, 2, ofctl_remove_bucket },
{ "dump-groups", "switch [group]",
1, 2, ofctl_dump_group_desc },
{ "dump-group-stats", "switch [group]",