X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fvconn.c;h=19a19786f1ed342c7ff301cdb1e7ba50bfc2a096;hb=ca069229880ba47ba100b62ed34c0c226355b0c6;hp=3cd2948745956b7d632538250988436a17317cb9;hpb=e8b52a913a8fc3d2ef0dae82eda5905668ebfae1;p=openvswitch diff --git a/lib/vconn.c b/lib/vconn.c index 3cd29487..19a19786 100644 --- a/lib/vconn.c +++ b/lib/vconn.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2009 Nicira Networks. + * Copyright (c) 2008, 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. @@ -90,7 +90,8 @@ check_vconn_classes(void) struct vconn_class *class = vconn_classes[i]; assert(class->name != NULL); assert(class->open != NULL); - if (class->close || class->recv || class->send || class->wait) { + 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); @@ -119,7 +120,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 @@ -208,6 +209,26 @@ vconn_open(const char *name, int min_version, struct vconn **vconnp) return EAFNOSUPPORT; } +/* Allows 'vconn' to perform maintenance activities, such as flushing output + * buffers. */ +void +vconn_run(struct vconn *vconn) +{ + if (vconn->class->run) { + (vconn->class->run)(vconn); + } +} + +/* Arranges for the poll loop to wake up when 'vconn' needs to perform + * maintenance activities. */ +void +vconn_run_wait(struct vconn *vconn) +{ + if (vconn->class->run_wait) { + (vconn->class->run_wait)(vconn); + } +} + int vconn_open_block(const char *name, int min_version, struct vconn **vconnp) { @@ -216,6 +237,8 @@ vconn_open_block(const char *name, int min_version, struct vconn **vconnp) error = vconn_open(name, min_version, &vconn); while (error == EAGAIN) { + vconn_run(vconn); + vconn_run_wait(vconn); vconn_connect_wait(vconn); poll_block(); error = vconn_connect(vconn); @@ -547,6 +570,8 @@ vconn_send_block(struct vconn *vconn, struct ofpbuf *msg) { int retval; while ((retval = vconn_send(vconn, msg)) == EAGAIN) { + vconn_run(vconn); + vconn_run_wait(vconn); vconn_send_wait(vconn); poll_block(); } @@ -559,6 +584,8 @@ vconn_recv_block(struct vconn *vconn, struct ofpbuf **msgp) { int retval; while ((retval = vconn_recv(vconn, msgp)) == EAGAIN) { + vconn_run(vconn); + vconn_run_wait(vconn); vconn_recv_wait(vconn); poll_block(); } @@ -865,6 +892,7 @@ make_flow_mod(uint16_t command, const flow_t *flow, size_t actions_len) memcpy(ofm->match.dl_src, flow->dl_src, sizeof ofm->match.dl_src); memcpy(ofm->match.dl_dst, flow->dl_dst, sizeof ofm->match.dl_dst); ofm->match.dl_vlan = flow->dl_vlan; + ofm->match.dl_vlan_pcp = flow->dl_vlan_pcp; ofm->match.dl_type = flow->dl_type; ofm->match.nw_src = flow->nw_src; ofm->match.nw_dst = flow->nw_dst; @@ -1042,10 +1070,10 @@ 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); + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } return 0; @@ -1077,22 +1105,22 @@ 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); - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } 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, array_elt_size, (got_size - min_size) % array_elt_size); free(type_name); - return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LENGTH); + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } if (n_array_elts) { *n_array_elts = (got_size - min_size) / array_elt_size; @@ -1119,16 +1147,16 @@ 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); + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } 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); + return ofp_mkerr(OFPET_BAD_REQUEST, OFPBRC_BAD_LEN); } n_actions = actions_len / sizeof(union ofp_action); @@ -1265,6 +1293,7 @@ check_action(const union ofp_action *a, unsigned int len, int max_ports) case OFPAT_STRIP_VLAN: case OFPAT_SET_NW_SRC: case OFPAT_SET_NW_DST: + case OFPAT_SET_NW_TOS: case OFPAT_SET_TP_SRC: case OFPAT_SET_TP_DST: return check_action_exact_len(a, len, 8); @@ -1282,7 +1311,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); } @@ -1312,7 +1342,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); } @@ -1360,7 +1390,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; @@ -1369,7 +1399,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; @@ -1384,7 +1414,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; } @@ -1396,7 +1426,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; @@ -1443,6 +1473,7 @@ vconn_init(struct vconn *vconn, struct vconn_class *class, int connect_status, vconn->local_ip = 0; vconn->local_port = 0; vconn->name = xstrdup(name); + assert(vconn->state != VCS_CONNECTING || class->connect); } void