/*
- * Copyright (c) 2009 Nicira Networks.
+ * Copyright (c) 2009, 2010 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include "discovery.h"
#include "dpif.h"
#include "dynamic-string.h"
-#include "executer.h"
#include "fail-open.h"
#include "in-band.h"
#include "mac-learning.h"
#include "shash.h"
#include "status.h"
#include "stp.h"
+#include "stream-ssl.h"
#include "svec.h"
#include "tag.h"
#include "timeval.h"
#include "unixctl.h"
#include "vconn.h"
-#include "vconn-ssl.h"
#include "xtoxll.h"
#define THIS_MODULE VLM_ofproto
};
static struct ofconn *ofconn_create(struct ofproto *, struct rconn *);
-static void ofconn_destroy(struct ofconn *, struct ofproto *);
+static void ofconn_destroy(struct ofconn *);
static void ofconn_run(struct ofconn *, struct ofproto *);
static void ofconn_wait(struct ofconn *);
static void queue_tx(struct ofpbuf *msg, const struct ofconn *ofconn,
struct discovery *discovery;
struct fail_open *fail_open;
struct pinsched *miss_sched, *action_sched;
- struct executer *executer;
struct netflow *netflow;
/* Flow table. */
dpif_recv_purge(dpif);
/* Initialize settings. */
- p = xcalloc(1, sizeof *p);
+ p = xzalloc(sizeof *p);
p->fallback_dpid = pick_fallback_dpid();
p->datapath_id = p->fallback_dpid;
p->manufacturer = xstrdup("Nicira Networks, Inc.");
p->discovery = NULL;
p->fail_open = NULL;
p->miss_sched = p->action_sched = NULL;
- p->executer = NULL;
p->netflow = NULL;
/* Initialize flow table. */
p->ss_cat = switch_status_register(p->switch_status, "remote",
rconn_status_cb, p->controller->rconn);
- /* Almost done... */
- error = init_ports(p);
- if (error) {
- ofproto_destroy(p);
- return error;
- }
-
/* Pick final datapath ID. */
p->datapath_id = pick_datapath_id(p);
VLOG_INFO("using datapath ID %012"PRIx64, p->datapath_id);
ofproto_set_netflow(struct ofproto *ofproto,
const struct netflow_options *nf_options)
{
- if (nf_options->collectors.n) {
+ if (nf_options && nf_options->collectors.n) {
if (!ofproto->netflow) {
ofproto->netflow = netflow_create();
}
}
}
-int
-ofproto_set_remote_execution(struct ofproto *ofproto, const char *command_acl,
- const char *command_dir)
-{
- if (command_acl) {
- if (!ofproto->executer) {
- return executer_create(command_acl, command_dir,
- &ofproto->executer);
- } else {
- executer_set_acl(ofproto->executer, command_acl, command_dir);
- }
- } else {
- executer_destroy(ofproto->executer);
- ofproto->executer = NULL;
- }
- return 0;
-}
-
uint64_t
ofproto_get_datapath_id(const struct ofproto *ofproto)
{
LIST_FOR_EACH_SAFE (ofconn, next_ofconn, struct ofconn, node,
&p->all_conns) {
- ofconn_destroy(ofconn, p);
+ ofconn_destroy(ofconn);
}
dpif_close(p->dpif);
fail_open_destroy(p->fail_open);
pinsched_destroy(p->miss_sched);
pinsched_destroy(p->action_sched);
- executer_destroy(p->executer);
netflow_destroy(p->netflow);
switch_status_unregister(p->ss_cat);
int error;
int i;
+ if (shash_is_empty(&p->port_by_name)) {
+ init_ports(p);
+ }
+
for (i = 0; i < 50; i++) {
struct ofpbuf *buf;
int error;
}
pinsched_run(p->miss_sched, send_packet_in_miss, p);
pinsched_run(p->action_sched, send_packet_in_action, p);
- if (p->executer) {
- executer_run(p->executer);
- }
LIST_FOR_EACH_SAFE (ofconn, next_ofconn, struct ofconn, node,
&p->all_conns) {
}
pinsched_wait(p->miss_sched);
pinsched_wait(p->action_sched);
- if (p->executer) {
- executer_wait(p->executer);
- }
if (!tag_set_is_empty(&p->revalidate_set)) {
poll_immediate_wake();
}
static struct ofport *
make_ofport(const struct odp_port *odp_port)
{
+ struct netdev_options netdev_options;
enum netdev_flags flags;
struct ofport *ofport;
struct netdev *netdev;
bool carrier;
int error;
- error = netdev_open(odp_port->devname, NETDEV_ETH_TYPE_NONE, &netdev);
+ memset(&netdev_options, 0, sizeof netdev_options);
+ netdev_options.name = odp_port->devname;
+ netdev_options.ethertype = NETDEV_ETH_TYPE_NONE;
+ netdev_options.may_open = true;
+
+ error = netdev_open(&netdev_options, &netdev);
if (error) {
VLOG_WARN_RL(&rl, "ignoring port %s (%"PRIu16") because netdev %s "
"cannot be opened (%s)",
}
static void
-ofconn_destroy(struct ofconn *ofconn, struct ofproto *p)
+ofconn_destroy(struct ofconn *ofconn)
{
- if (p->executer) {
- executer_rconn_closing(p->executer, ofconn->rconn);
- }
-
list_remove(&ofconn->node);
rconn_destroy(ofconn->rconn);
rconn_packet_counter_destroy(ofconn->packet_in_counter);
}
if (ofconn != p->controller && !rconn_is_alive(ofconn->rconn)) {
- ofconn_destroy(ofconn, p);
+ ofconn_destroy(ofconn);
}
}
const union ofp_action *actions, size_t n_actions,
uint16_t idle_timeout, uint16_t hard_timeout)
{
- struct rule *rule = xcalloc(1, sizeof *rule);
+ struct rule *rule = xzalloc(sizeof *rule);
rule->idle_timeout = idle_timeout;
rule->hard_timeout = hard_timeout;
rule->used = rule->created = time_msec();
&put)) {
rule->installed = true;
if (displaced_rule) {
- update_stats(p, rule, &put.flow.stats);
+ update_stats(p, displaced_rule, &put.flow.stats);
rule_post_uninstall(p, displaced_rule);
}
}
static void
rule_update_actions(struct ofproto *ofproto, struct rule *rule)
{
- bool actions_changed = rule_make_actions(ofproto, rule, NULL);
+ bool actions_changed;
+ uint16_t new_out_iface, old_out_iface;
+
+ old_out_iface = rule->nf_flow.output_iface;
+ actions_changed = rule_make_actions(ofproto, rule, NULL);
+
if (rule->may_install) {
if (rule->installed) {
if (actions_changed) {
- /* XXX should really do rule_post_uninstall() for the *old* set
- * of actions, and distinguish the old stats from the new. */
struct odp_flow_put put;
- do_put_flow(ofproto, rule, ODPPF_CREATE | ODPPF_MODIFY, &put);
+ do_put_flow(ofproto, rule, ODPPF_CREATE | ODPPF_MODIFY
+ | ODPPF_ZERO_STATS, &put);
+ update_stats(ofproto, rule, &put.flow.stats);
+
+ /* Temporarily set the old output iface so that NetFlow
+ * messages have the correct output interface for the old
+ * stats. */
+ new_out_iface = rule->nf_flow.output_iface;
+ rule->nf_flow.output_iface = old_out_iface;
+ rule_post_uninstall(ofproto, rule);
+ rule->nf_flow.output_iface = new_out_iface;
}
} else {
rule_install(ofproto, rule, NULL);
oa->nw_addr.nw_addr = ia->nw_addr.nw_addr;
break;
+ case OFPAT_SET_NW_DST:
+ oa = odp_actions_add(ctx->out, ODPAT_SET_NW_DST);
+ oa->nw_addr.nw_addr = ia->nw_addr.nw_addr;
+ break;
+
case OFPAT_SET_TP_SRC:
oa = odp_actions_add(ctx->out, ODPAT_SET_TP_SRC);
oa->tp_port.tp_port = ia->tp_port.tp_port;
break;
+ case OFPAT_SET_TP_DST:
+ oa = odp_actions_add(ctx->out, ODPAT_SET_TP_DST);
+ oa->tp_port.tp_port = ia->tp_port.tp_port;
+ break;
+
case OFPAT_VENDOR:
xlate_nicira_action(ctx, (const struct nx_action_header *) ia);
break;
byte_count = rule->byte_count;
n_odp_flows = rule->cr.wc.wildcards ? list_size(&rule->list) : 1;
- odp_flows = xcalloc(1, n_odp_flows * sizeof *odp_flows);
+ odp_flows = xzalloc(n_odp_flows * sizeof *odp_flows);
if (rule->cr.wc.wildcards) {
size_t i = 0;
LIST_FOR_EACH (subrule, struct rule, list, &rule->list) {
long long int used = msec_from_nsec(stats->used_sec, stats->used_nsec);
if (used > rule->used) {
rule->used = used;
+ if (rule->super && used > rule->super->used) {
+ rule->super->used = used;
+ }
netflow_flow_update_time(ofproto->netflow, &rule->nf_flow, used);
}
}
case NXT_ACT_GET_CONFIG:
return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE); /* XXX */
- case NXT_COMMAND_REQUEST:
- if (p->executer) {
- return executer_handle_request(p->executer, ofconn->rconn, msg);
- }
- break;
-
case NXT_MGMT:
return handle_ofmp(p, ofconn, msg);
}
}
COVERAGE_INC(ofproto_expired);
+
+ /* Update stats. This code will be a no-op if the rule expired
+ * due to an idle timeout. */
if (rule->cr.wc.wildcards) {
- /* Update stats. (This code will be a no-op if the rule expired
- * due to an idle timeout, because in that case the rule has no
- * subrules left.) */
struct rule *subrule, *next;
LIST_FOR_EACH_SAFE (subrule, next, struct rule, list, &rule->list) {
rule_remove(p, subrule);
}
+ } else {
+ rule_uninstall(p, rule);
}
- send_flow_exp(p, rule, now,
- (now >= hard_expire
- ? OFPER_HARD_TIMEOUT : OFPER_IDLE_TIMEOUT));
+ if (!rule_is_hidden(rule)) {
+ send_flow_exp(p, rule, now,
+ (now >= hard_expire
+ ? OFPER_HARD_TIMEOUT : OFPER_IDLE_TIMEOUT));
+ }
rule_remove(p, rule);
}