X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=7df8600e54b853c9c8859b691b7968440147bfe7;hb=1dfee98d87605bc52ed58738edf01e201b189615;hp=339b9605dbf4f3198a834f2f283934e8ff0c01cb;hpb=b9298d3f825703063c9538aa37407da43e1e4781;p=openvswitch diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 339b9605..7df8600e 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2010 Nicira Networks. + * Copyright (c) 2009, 2010, 2011 Nicira Networks. * Copyright (c) 2010 Jean Tourrilhes - HP-Labs. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ #include "hmap.h" #include "in-band.h" #include "mac-learning.h" +#include "multipath.h" #include "netdev.h" #include "netflow.h" #include "netlink.h" @@ -225,7 +226,7 @@ struct facet { bool installed; /* Installed in datapath? */ bool may_install; /* True ordinarily; false if actions must * be reassessed for every packet. */ - unsigned int actions_len; /* Number of bytes in actions[]. */ + size_t actions_len; /* Number of bytes in actions[]. */ struct nlattr *actions; /* Datapath actions. */ tag_type tags; /* Tags (set only by hooks). */ struct netflow_flow nf_flow; /* Per-flow NetFlow tracking data. */ @@ -1480,7 +1481,8 @@ ofproto_flush_flows(struct ofproto *ofproto) static void reinit_ports(struct ofproto *p) { - struct svec devnames; + struct shash_node *node; + struct shash devnames; struct ofport *ofport; struct odp_port *odp_ports; size_t n_odp_ports; @@ -1488,21 +1490,20 @@ reinit_ports(struct ofproto *p) COVERAGE_INC(ofproto_reinit_ports); - svec_init(&devnames); + shash_init(&devnames); HMAP_FOR_EACH (ofport, hmap_node, &p->ports) { - svec_add (&devnames, ofport->opp.name); + shash_add_once (&devnames, ofport->opp.name, NULL); } dpif_port_list(p->dpif, &odp_ports, &n_odp_ports); for (i = 0; i < n_odp_ports; i++) { - svec_add (&devnames, odp_ports[i].devname); + shash_add_once (&devnames, odp_ports[i].devname, NULL); } free(odp_ports); - svec_sort_unique(&devnames); - for (i = 0; i < devnames.n; i++) { - update_port(p, devnames.names[i]); + SHASH_FOR_EACH (node, &devnames) { + update_port(p, node->name); } - svec_destroy(&devnames); + shash_destroy(&devnames); } static struct ofport * @@ -2050,7 +2051,7 @@ rule_has_out_port(const struct rule *rule, ovs_be16 out_port) * Takes ownership of 'packet'. */ static bool execute_odp_actions(struct ofproto *ofproto, uint16_t in_port, - const struct nlattr *odp_actions, unsigned int actions_len, + const struct nlattr *odp_actions, size_t actions_len, struct ofpbuf *packet) { if (actions_len == NLA_ALIGN(NLA_HDRLEN + sizeof(uint64_t)) @@ -2250,6 +2251,9 @@ facet_make_actions(struct ofproto *p, struct facet *facet, action_xlate_ctx_init(&ctx, p, &facet->flow, packet); odp_actions = xlate_actions(&ctx, rule->actions, rule->n_actions); + facet->tags = ctx.tags; + facet->may_install = ctx.may_set_up_flow; + facet->nf_flow.output_iface = ctx.nf_output_iface; if (facet->actions_len != odp_actions->size || memcmp(facet->actions, odp_actions->data, odp_actions->size)) { @@ -2475,8 +2479,6 @@ facet_revalidate(struct ofproto *ofproto, struct facet *facet) facet_flush_stats(ofproto, facet); } - ofpbuf_delete(odp_actions); - /* Update 'facet' now that we've taken care of all the old state. */ facet->tags = ctx.tags; facet->nf_flow.output_iface = ctx.nf_output_iface; @@ -2494,6 +2496,8 @@ facet_revalidate(struct ofproto *ofproto, struct facet *facet) facet->used = new_rule->created; } + ofpbuf_delete(odp_actions); + return true; } @@ -2511,7 +2515,7 @@ static void send_error_oh(const struct ofconn *ofconn, const struct ofp_header *oh, int error) { - struct ofpbuf *buf = make_ofp_error_msg(error, oh); + struct ofpbuf *buf = ofputil_encode_error_msg(error, oh); if (buf) { COVERAGE_INC(ofproto_error); queue_tx(buf, ofconn, ofconn->reply_counter); @@ -2619,7 +2623,7 @@ handle_set_config(struct ofconn *ofconn, const struct ofp_switch_config *osc) /* Maximum depth of flow table recursion (due to NXAST_RESUBMIT actions) in a * flow translation. */ -#define MAX_RESUBMIT_RECURSION 8 +#define MAX_RESUBMIT_RECURSION 16 static void do_xlate_actions(const union ofp_action *in, size_t n_in, struct action_xlate_ctx *ctx); @@ -2677,7 +2681,7 @@ xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port) ctx->recurse--; } } else { - struct vlog_rate_limit recurse_rl = VLOG_RATE_LIMIT_INIT(1, 1); + static struct vlog_rate_limit recurse_rl = VLOG_RATE_LIMIT_INIT(1, 1); VLOG_ERR_RL(&recurse_rl, "NXAST_RESUBMIT recursed over %d times", MAX_RESUBMIT_RECURSION); @@ -2854,17 +2858,29 @@ xlate_set_dl_tci(struct action_xlate_ctx *ctx) } } +struct xlate_reg_state { + ovs_be16 vlan_tci; + ovs_be64 tun_id; +}; + static void -xlate_reg_move_action(struct action_xlate_ctx *ctx, - const struct nx_action_reg_move *narm) +save_reg_state(const struct action_xlate_ctx *ctx, + struct xlate_reg_state *state) { - ovs_be16 old_tci = ctx->flow.vlan_tci; - - nxm_execute_reg_move(narm, &ctx->flow); + state->vlan_tci = ctx->flow.vlan_tci; + state->tun_id = ctx->flow.tun_id; +} - if (ctx->flow.vlan_tci != old_tci) { +static void +update_reg_state(struct action_xlate_ctx *ctx, + const struct xlate_reg_state *state) +{ + if (ctx->flow.vlan_tci != state->vlan_tci) { xlate_set_dl_tci(ctx); } + if (ctx->flow.tun_id != state->tun_id) { + nl_msg_put_be64(ctx->odp_actions, ODPAT_SET_TUNNEL, ctx->flow.tun_id); + } } static void @@ -2874,7 +2890,9 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, const struct nx_action_resubmit *nar; const struct nx_action_set_tunnel *nast; const struct nx_action_set_queue *nasq; + const struct nx_action_multipath *nam; enum nx_action_subtype subtype = ntohs(nah->subtype); + struct xlate_reg_state state; ovs_be64 tun_id; assert(nah->vendor == htonl(NX_VENDOR_ID)); @@ -2907,12 +2925,18 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, break; case NXAST_REG_MOVE: - xlate_reg_move_action(ctx, (const struct nx_action_reg_move *) nah); + save_reg_state(ctx, &state); + nxm_execute_reg_move((const struct nx_action_reg_move *) nah, + &ctx->flow); + update_reg_state(ctx, &state); break; case NXAST_REG_LOAD: + save_reg_state(ctx, &state); nxm_execute_reg_load((const struct nx_action_reg_load *) nah, &ctx->flow); + update_reg_state(ctx, &state); + break; case NXAST_NOTE: /* Nothing to do. */ @@ -2924,6 +2948,11 @@ xlate_nicira_action(struct action_xlate_ctx *ctx, ctx->flow.tun_id = tun_id; break; + case NXAST_MULTIPATH: + nam = (const struct nx_action_multipath *) nah; + multipath_execute(nam, &ctx->flow); + break; + /* If you add a new action here that modifies flow data, don't forget to * update the flow key in ctx->flow at the same time. */ @@ -3255,7 +3284,7 @@ make_nxstats_reply(ovs_be32 xid, ovs_be32 subtype, size_t body_len) nsm->type = htons(OFPST_VENDOR); nsm->flags = htons(0); nsm->vendor = htonl(NX_VENDOR_ID); - nsm->subtype = htonl(subtype); + nsm->subtype = subtype; return msg; } @@ -3520,8 +3549,8 @@ put_nx_flow_stats(struct ofconn *ofconn, struct rule *rule, act_len = sizeof *rule->actions * rule->n_actions; - start_len = (*replyp)->size; append_nxstats_reply(sizeof *nfs + NXM_MAX_LEN + act_len, ofconn, replyp); + start_len = (*replyp)->size; reply = *replyp; nfs = ofpbuf_put_uninit(reply, sizeof *nfs); @@ -4675,7 +4704,7 @@ compose_ofp_flow_removed(struct ofconn *ofconn, const struct rule *rule, struct ofp_flow_removed *ofr; struct ofpbuf *buf; - ofr = make_openflow(sizeof *ofr, OFPT_FLOW_REMOVED, &buf); + ofr = make_openflow_xid(sizeof *ofr, OFPT_FLOW_REMOVED, htonl(0), &buf); ofputil_cls_rule_to_match(&rule->cr, ofconn->flow_format, &ofr->match, rule->flow_cookie, &ofr->cookie); ofr->priority = htons(rule->cr.priority); @@ -4695,10 +4724,10 @@ compose_nx_flow_removed(const struct rule *rule, uint8_t reason) struct ofpbuf *buf; int match_len; - nfr = make_nxmsg(sizeof *nfr, NXT_FLOW_REMOVED, &buf); - + make_nxmsg_xid(sizeof *nfr, NXT_FLOW_REMOVED, htonl(0), &buf); match_len = nx_put_match(buf, &rule->cr); + nfr = buf->data; nfr->cookie = rule->flow_cookie; nfr->priority = htons(rule->cr.priority); nfr->reason = reason; @@ -4997,7 +5026,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, const char *args_, struct ds result; struct flow flow; uint16_t in_port; - ovs_be32 tun_id; + ovs_be64 tun_id; char *s; ofpbuf_init(&packet, strlen(args) / 2); @@ -5019,7 +5048,7 @@ ofproto_unixctl_trace(struct unixctl_conn *conn, const char *args_, goto exit; } - tun_id = ntohl(strtoul(tun_id_s, NULL, 10)); + tun_id = htonll(strtoull(tun_id_s, NULL, 10)); in_port = ofp_port_to_odp_port(atoi(in_port_s)); packet_s = ofpbuf_put_hex(&packet, packet_s, NULL);