X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=10b4796f19a2a2e3d3667f313eef564dca7d22b6;hb=898b7f8d4131c9dae8d292bfacd99465fb52b26c;hp=2894e2d331e9799f8c4c2788d2e361ed6d4fca60;hpb=4836f9f2bfa5dc0531bd1d828aae96ccd6b415cb;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 2894e2d3..10b4796f 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1,5 +1,5 @@ /* - * 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. @@ -27,7 +27,6 @@ #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" @@ -38,7 +37,6 @@ #include "ofpbuf.h" #include "openflow/nicira-ext.h" #include "openflow/openflow.h" -#include "openflow/openflow-mgmt.h" #include "openvswitch/datapath-protocol.h" #include "packets.h" #include "pinsched.h" @@ -49,12 +47,12 @@ #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 @@ -176,7 +174,7 @@ struct ofconn { }; 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, @@ -186,7 +184,6 @@ struct ofproto { /* Settings. */ uint64_t datapath_id; /* Datapath ID. */ uint64_t fallback_dpid; /* Datapath ID if no better choice found. */ - uint64_t mgmt_id; /* Management channel identifier. */ char *manufacturer; /* Manufacturer. */ char *hardware; /* Hardware. */ char *software; /* Software version. */ @@ -207,7 +204,6 @@ struct ofproto { struct discovery *discovery; struct fail_open *fail_open; struct pinsched *miss_sched, *action_sched; - struct executer *executer; struct netflow *netflow; /* Flow table. */ @@ -259,7 +255,8 @@ static int init_ports(struct ofproto *); static void reinit_ports(struct ofproto *); int -ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux, +ofproto_create(const char *datapath, const char *datapath_type, + const struct ofhooks *ofhooks, void *aux, struct ofproto **ofprotop) { struct odp_stats stats; @@ -270,7 +267,7 @@ ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux, *ofprotop = NULL; /* Connect to datapath and start listening for messages. */ - error = dpif_open(datapath, &dpif); + error = dpif_open(datapath, datapath_type, &dpif); if (error) { VLOG_ERR("failed to open datapath %s: %s", datapath, strerror(error)); return error; @@ -293,7 +290,7 @@ ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux, 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."); @@ -314,7 +311,6 @@ ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux, p->discovery = NULL; p->fail_open = NULL; p->miss_sched = p->action_sched = NULL; - p->executer = NULL; p->netflow = NULL; /* Initialize flow table. */ @@ -348,13 +344,6 @@ ofproto_create(const char *datapath, const struct ofhooks *ofhooks, void *aux, 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); @@ -374,12 +363,6 @@ ofproto_set_datapath_id(struct ofproto *p, uint64_t datapath_id) } } -void -ofproto_set_mgmt_id(struct ofproto *p, uint64_t mgmt_id) -{ - p->mgmt_id = mgmt_id; -} - void ofproto_set_probe_interval(struct ofproto *p, int probe_interval) { @@ -536,7 +519,7 @@ int 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(); } @@ -603,36 +586,12 @@ ofproto_set_stp(struct ofproto *ofproto UNUSED, bool enable_stp) } } -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) { return ofproto->datapath_id; } -uint64_t -ofproto_get_mgmt_id(const struct ofproto *ofproto) -{ - return ofproto->mgmt_id; -} - int ofproto_get_probe_interval(const struct ofproto *ofproto) { @@ -700,7 +659,7 @@ ofproto_destroy(struct ofproto *p) LIST_FOR_EACH_SAFE (ofconn, next_ofconn, struct ofconn, node, &p->all_conns) { - ofconn_destroy(ofconn, p); + ofconn_destroy(ofconn); } dpif_close(p->dpif); @@ -716,7 +675,6 @@ ofproto_destroy(struct ofproto *p) 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); @@ -765,6 +723,10 @@ ofproto_run1(struct ofproto *p) 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; @@ -812,9 +774,6 @@ ofproto_run1(struct ofproto *p) } 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) { @@ -923,9 +882,6 @@ ofproto_wait(struct ofproto *p) } 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(); } @@ -1097,13 +1053,19 @@ refresh_port_groups(struct ofproto *p) 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)", @@ -1328,12 +1290,8 @@ ofconn_create(struct ofproto *p, struct rconn *rconn) } 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); @@ -1366,7 +1324,7 @@ ofconn_run(struct ofconn *ofconn, struct ofproto *p) } if (ofconn != p->controller && !rconn_is_alive(ofconn->rconn)) { - ofconn_destroy(ofconn, p); + ofconn_destroy(ofconn); } } @@ -1388,7 +1346,7 @@ rule_create(struct ofproto *ofproto, struct rule *super, 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(); @@ -1628,7 +1586,7 @@ rule_install(struct ofproto *p, struct rule *rule, struct rule *displaced_rule) &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); } } @@ -1652,14 +1610,27 @@ rule_reinstall(struct ofproto *ofproto, struct rule *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); @@ -2147,11 +2118,21 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, 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; @@ -2469,7 +2450,7 @@ query_stats(struct ofproto *p, struct rule *rule, 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) { @@ -2927,58 +2908,6 @@ handle_flow_mod(struct ofproto *p, struct ofconn *ofconn, } } -static void -send_capability_reply(struct ofproto *p, struct ofconn *ofconn, uint32_t xid) -{ - struct ofmp_capability_reply *ocr; - struct ofpbuf *b; - char capabilities[] = "com.nicira.mgmt.manager=false\n"; - - ocr = make_openflow_xid(sizeof(*ocr), OFPT_VENDOR, xid, &b); - ocr->header.header.vendor = htonl(NX_VENDOR_ID); - ocr->header.header.subtype = htonl(NXT_MGMT); - ocr->header.type = htons(OFMPT_CAPABILITY_REPLY); - - ocr->format = htonl(OFMPCOF_SIMPLE); - ocr->mgmt_id = htonll(p->mgmt_id); - - ofpbuf_put(b, capabilities, strlen(capabilities)); - - queue_tx(b, ofconn, ofconn->reply_counter); -} - -static int -handle_ofmp(struct ofproto *p, struct ofconn *ofconn, - struct ofmp_header *ofmph) -{ - size_t msg_len = ntohs(ofmph->header.header.length); - if (msg_len < sizeof(*ofmph)) { - VLOG_WARN_RL(&rl, "dropping short managment message: %zu\n", msg_len); - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); - } - - if (ofmph->type == htons(OFMPT_CAPABILITY_REQUEST)) { - struct ofmp_capability_request *ofmpcr; - - if (msg_len < sizeof(struct ofmp_capability_request)) { - VLOG_WARN_RL(&rl, "dropping short capability request: %zu\n", - msg_len); - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); - } - - ofmpcr = (struct ofmp_capability_request *)ofmph; - if (ofmpcr->format != htonl(OFMPCAF_SIMPLE)) { - /* xxx Find a better type than bad subtype */ - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE); - } - - send_capability_reply(p, ofconn, ofmph->header.header.xid); - return 0; - } else { - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE); - } -} - static int handle_vendor(struct ofproto *p, struct ofconn *ofconn, void *msg) { @@ -3000,21 +2929,6 @@ handle_vendor(struct ofproto *p, struct ofconn *ofconn, void *msg) case NXT_STATUS_REQUEST: return switch_status_handle_request(p->switch_status, ofconn->rconn, msg); - - case NXT_ACT_SET_CONFIG: - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE); /* XXX */ - - 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); } return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_SUBTYPE); @@ -3300,19 +3214,23 @@ expire_rule(struct cls_rule *cls_rule, void *p_) } 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); }