X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fvconn.c;h=f72dbe3ed675aee0227275e69137c9ef080ed885;hb=67a4917b07031b387beafaedce413b4207214059;hp=b4840512f8413a516b6f7e953402a7d228bf30ba;hpb=5fe577ebbec3cbcc6f77d966ed04f099b40a0d0b;p=openvswitch diff --git a/lib/vconn.c b/lib/vconn.c index b4840512..f72dbe3e 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -1,17 +1,17 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 2009, 2010 Nicira Networks. * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. + * 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: * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * 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 @@ -119,7 +119,7 @@ check_vconn_classes(void) * connection methods supported by the vconn. If 'bootstrap' is true, also * advertises options to bootstrap the CA certificate. */ void -vconn_usage(bool active, bool passive, bool bootstrap UNUSED) +vconn_usage(bool active, bool passive, bool bootstrap OVS_UNUSED) { /* Really this should be implemented via callbacks into the vconn * providers, but that seems too heavy-weight to bother with at the @@ -128,23 +128,23 @@ vconn_usage(bool active, bool passive, bool bootstrap UNUSED) printf("\n"); if (active) { printf("Active OpenFlow connection methods:\n"); - printf(" tcp:HOST[:PORT] " - "PORT (default: %d) on remote TCP HOST\n", OFP_TCP_PORT); + printf(" tcp:IP[:PORT] " + "PORT (default: %d) at remote IP\n", OFP_TCP_PORT); #ifdef HAVE_OPENSSL - printf(" ssl:HOST[:PORT] " - "SSL PORT (default: %d) on remote HOST\n", OFP_SSL_PORT); + printf(" ssl:IP[:PORT] " + "SSL PORT (default: %d) at remote IP\n", OFP_SSL_PORT); #endif printf(" unix:FILE Unix domain socket named FILE\n"); } if (passive) { printf("Passive OpenFlow connection methods:\n"); - printf(" ptcp:[PORT] " - "listen to TCP PORT (default: %d)\n", + printf(" ptcp:[PORT][:IP] " + "listen to TCP PORT (default: %d) on IP\n", OFP_TCP_PORT); #ifdef HAVE_OPENSSL - printf(" pssl:[PORT] " - "listen for SSL on PORT (default: %d)\n", + printf(" pssl:[PORT][:IP] " + "listen for SSL on PORT (default: %d) on IP\n", OFP_SSL_PORT); #endif printf(" punix:FILE " @@ -251,9 +251,34 @@ vconn_get_name(const struct vconn *vconn) /* Returns the IP address of the peer, or 0 if the peer is not connected over * an IP-based protocol or if its IP address is not yet known. */ uint32_t -vconn_get_ip(const struct vconn *vconn) +vconn_get_remote_ip(const struct vconn *vconn) { - return vconn->ip; + return vconn->remote_ip; +} + +/* Returns the transport port of the peer, or 0 if the connection does not + * contain a port or if the port is not yet known. */ +uint16_t +vconn_get_remote_port(const struct vconn *vconn) +{ + return vconn->remote_port; +} + +/* Returns the IP address used to connect to the peer, or 0 if the + * connection is not an IP-based protocol or if its IP address is not + * yet known. */ +uint32_t +vconn_get_local_ip(const struct vconn *vconn) +{ + return vconn->local_ip; +} + +/* Returns the transport port used to connect to the peer, or 0 if the + * connection does not contain a port or if the port is not yet known. */ +uint16_t +vconn_get_local_port(const struct vconn *vconn) +{ + return vconn->local_port; } static void @@ -886,6 +911,28 @@ make_add_simple_flow(const flow_t *flow, return buffer; } +struct ofpbuf * +make_packet_in(uint32_t buffer_id, uint16_t in_port, uint8_t reason, + const struct ofpbuf *payload, int max_send_len) +{ + struct ofp_packet_in *opi; + struct ofpbuf *buf; + int send_len; + + send_len = MIN(max_send_len, payload->size); + buf = ofpbuf_new(sizeof *opi + send_len); + opi = put_openflow_xid(offsetof(struct ofp_packet_in, data), + OFPT_PACKET_IN, 0, buf); + opi->buffer_id = htonl(buffer_id); + opi->total_len = htons(payload->size); + opi->in_port = htons(in_port); + opi->reason = reason; + ofpbuf_put(buf, payload->data, send_len); + update_openflow_length(buf); + + return buf; +} + struct ofpbuf * make_packet_out(const struct ofpbuf *packet, uint32_t buffer_id, uint16_t in_port, @@ -995,7 +1042,7 @@ check_ofp_message(const struct ofp_header *msg, uint8_t type, size_t size) if (got_size != size) { char *type_name = ofp_message_type_to_string(type); VLOG_WARN_RL(&bad_ofmsg_rl, - "received %s message of length %"PRIu16" (expected %zu)", + "received %s message of length %zu (expected %zu)", type_name, got_size, size); free(type_name); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); @@ -1030,7 +1077,7 @@ check_ofp_message_array(const struct ofp_header *msg, uint8_t type, got_size = ntohs(msg->length); if (got_size < min_size) { char *type_name = ofp_message_type_to_string(type); - VLOG_WARN_RL(&bad_ofmsg_rl, "received %s message of length %"PRIu16" " + VLOG_WARN_RL(&bad_ofmsg_rl, "received %s message of length %zu " "(expected at least %zu)", type_name, got_size, min_size); free(type_name); @@ -1039,7 +1086,7 @@ check_ofp_message_array(const struct ofp_header *msg, uint8_t type, if ((got_size - min_size) % array_elt_size) { char *type_name = ofp_message_type_to_string(type); VLOG_WARN_RL(&bad_ofmsg_rl, - "received %s message of bad length %"PRIu16": the " + "received %s message of bad length %zu: the " "excess over %zu (%zu) is not evenly divisible by %zu " "(remainder is %zu)", type_name, got_size, min_size, got_size - min_size, @@ -1072,13 +1119,13 @@ check_ofp_packet_out(const struct ofp_header *oh, struct ofpbuf *data, actions_len = ntohs(opo->actions_len); if (actions_len > extra) { - VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out claims %zu bytes of actions " + VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out claims %u bytes of actions " "but message has room for only %zu bytes", actions_len, extra); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); } if (actions_len % sizeof(union ofp_action)) { - VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out claims %zu bytes of actions, " + VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out claims %u bytes of actions, " "which is not a multiple of %zu", actions_len, sizeof(union ofp_action)); return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); @@ -1205,7 +1252,7 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports) { int error; - switch (a->type) { + switch (ntohs(a->type)) { case OFPAT_OUTPUT: error = check_action_port(ntohs(a->output.port), max_ports); if (error) { @@ -1235,7 +1282,8 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports) break; default: - VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16, a->type); + VLOG_WARN_RL(&bad_ofmsg_rl, "unknown action type %"PRIu16, + ntohs(a->type)); return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_TYPE); } @@ -1265,7 +1313,7 @@ validate_actions(const union ofp_action *actions, size_t n_actions, if (n_slots > slots_left) { VLOG_DBG_RL(&bad_ofmsg_rl, - "action requires %u slots but only %td remain", + "action requires %u slots but only %u remain", n_slots, slots_left); return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_LEN); } @@ -1313,7 +1361,7 @@ normalize_match(struct ofp_match *m) if (wc & OFPFW_DL_TYPE) { m->dl_type = 0; - /* Can't sensibly m on network or transport headers if the + /* Can't sensibly match on network or transport headers if the * data link type is unknown. */ wc |= OFPFW_NW | OFPFW_TP; m->nw_src = m->nw_dst = m->nw_proto = 0; @@ -1322,7 +1370,7 @@ normalize_match(struct ofp_match *m) if (wc & OFPFW_NW_PROTO) { m->nw_proto = 0; - /* Can't sensibly m on transport headers if the network + /* Can't sensibly match on transport headers if the network * protocol is unknown. */ wc |= OFPFW_TP; m->tp_src = m->tp_dst = 0; @@ -1337,7 +1385,7 @@ normalize_match(struct ofp_match *m) } } else { /* Transport layer fields will always be extracted as zeros, so we - * can do an exact-m on those values. */ + * can do an exact-match on those values. */ wc &= ~OFPFW_TP; m->tp_src = m->tp_dst = 0; } @@ -1349,7 +1397,7 @@ normalize_match(struct ofp_match *m) } } else { /* Network and transport layer fields will always be extracted as - * zeros, so we can do an exact-m on those values. */ + * zeros, so we can do an exact-match on those values. */ wc &= ~(OFPFW_NW | OFPFW_TP); m->nw_proto = m->nw_src = m->nw_dst = 0; m->tp_src = m->tp_dst = 0; @@ -1363,9 +1411,26 @@ normalize_match(struct ofp_match *m) m->wildcards = htonl(wc); } +/* Initializes 'vconn' as a new vconn named 'name', implemented via 'class'. + * The initial connection status, supplied as 'connect_status', is interpreted + * as follows: + * + * - 0: 'vconn' is connected. Its 'send' and 'recv' functions may be + * called in the normal fashion. + * + * - EAGAIN: 'vconn' is trying to complete a connection. Its 'connect' + * function should be called to complete the connection. + * + * - Other positive errno values indicate that the connection failed with + * the specified error. + * + * After calling this function, vconn_close() must be used to destroy 'vconn', + * otherwise resources will be leaked. + * + * The caller retains ownership of 'name'. */ void vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, - uint32_t ip, const char *name, bool reconnectable) + const char *name) { vconn->class = class; vconn->state = (connect_status == EAGAIN ? VCS_CONNECTING @@ -1374,9 +1439,35 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, vconn->error = connect_status; vconn->version = -1; vconn->min_version = -1; - vconn->ip = ip; + vconn->remote_ip = 0; + vconn->remote_port = 0; + vconn->local_ip = 0; + vconn->local_port = 0; vconn->name = xstrdup(name); - vconn->reconnectable = reconnectable; +} + +void +vconn_set_remote_ip(struct vconn *vconn, uint32_t ip) +{ + vconn->remote_ip = ip; +} + +void +vconn_set_remote_port(struct vconn *vconn, uint16_t port) +{ + vconn->remote_port = port; +} + +void +vconn_set_local_ip(struct vconn *vconn, uint32_t ip) +{ + vconn->local_ip = ip; +} + +void +vconn_set_local_port(struct vconn *vconn, uint16_t port) +{ + vconn->local_port = port; } void