From: Ben Pfaff Date: Fri, 1 May 2009 20:35:36 +0000 (-0700) Subject: secchan: Honor OFPPC_NO_RECV, OFPPC_NO_RECV_STP, OFPPC_NO_FWD. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cdbaf58a7a947d2b0adfe6462ecd345ef03b95f;p=openvswitch secchan: Honor OFPPC_NO_RECV, OFPPC_NO_RECV_STP, OFPPC_NO_FWD. The refactoring of secchan and the kernel module dropped support for these (required) OpenFlow port flags. This commit reimplements them. --- diff --git a/MISSING b/MISSING index ec3d755d..b55253fb 100644 --- a/MISSING +++ b/MISSING @@ -6,9 +6,6 @@ reimplement them with the new architecture: - STP support in secchan (note that this is distinct from STP support in vswitchd). -- The OFPPC_NO_RECV, OFPPC_NO_RECV_STP, and OFPPC_NO_FWD bits in port - configurations. - - SNAT support in secchan (but SNAT is still supported in the kernel datapath). diff --git a/secchan/ofproto.c b/secchan/ofproto.c index 71eaca4d..2252c0e9 100644 --- a/secchan/ofproto.c +++ b/secchan/ofproto.c @@ -63,6 +63,7 @@ #include "rconn.h" #include "shash.h" #include "status.h" +#include "stp.h" #include "svec.h" #include "tag.h" #include "timeval.h" @@ -1804,12 +1805,6 @@ handle_set_config(struct ofproto *p, struct ofconn *ofconn, return 0; } -static void -add_output_action(struct odp_actions *actions, uint16_t port) -{ - odp_actions_add(actions, ODPAT_OUTPUT)->output.port = port; -} - static void add_output_group_action(struct odp_actions *actions, uint16_t group) { @@ -1843,6 +1838,15 @@ struct action_xlate_ctx { static void do_xlate_actions(const union ofp_action *in, size_t n_in, struct action_xlate_ctx *ctx); +static void +add_output_action(struct action_xlate_ctx *ctx, uint16_t port) +{ + const struct ofport *ofport = port_array_get(&ctx->ofproto->ports, port); + if (!ofport || !(ofport->opp.config & OFPPC_NO_FWD)) { + odp_actions_add(ctx->out, ODPAT_OUTPUT)->output.port = port; + } +} + static struct rule * lookup_valid_rule(struct ofproto *ofproto, const flow_t *flow) { @@ -1892,7 +1896,7 @@ xlate_output_action(struct action_xlate_ctx *ctx, switch (ntohs(oao->port)) { case OFPP_IN_PORT: - add_output_action(ctx->out, ctx->flow->in_port); + add_output_action(ctx, ctx->flow->in_port); break; case OFPP_TABLE: xlate_table_action(ctx, ctx->flow->in_port); @@ -1914,12 +1918,12 @@ xlate_output_action(struct action_xlate_ctx *ctx, add_controller_action(ctx->out, oao); break; case OFPP_LOCAL: - add_output_action(ctx->out, ODPP_LOCAL); + add_output_action(ctx, ODPP_LOCAL); break; default: odp_port = ofp_port_to_odp_port(ntohs(oao->port)); if (odp_port != ctx->flow->in_port) { - add_output_action(ctx->out, odp_port); + add_output_action(ctx, odp_port); } break; } @@ -1959,6 +1963,15 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, { struct actions_iterator iter; const union ofp_action *ia; + const struct ofport *port; + + port = port_array_get(&ctx->ofproto->ports, ctx->flow->in_port); + if (port && port->opp.config & (OFPPC_NO_RECV | OFPPC_NO_RECV_STP) && + port->opp.config & (eth_addr_equals(ctx->flow->dl_dst, stp_eth_addr) + ? OFPPC_NO_RECV_STP : OFPPC_NO_RECV)) { + /* Drop this flow. */ + return; + } for (ia = actions_first(&iter, in, n_in); ia; ia = actions_next(&iter)) { uint16_t type = ntohs(ia->type); @@ -2098,22 +2111,16 @@ update_port_config(struct ofproto *p, struct ofport *port, netdev_turn_flags_on(port->netdev, NETDEV_UP, true); } } - if (mask & OFPPC_NO_STP) { - /* XXX */ - } - if (mask & OFPPC_NO_RECV) { - /* XXX */ - } - if (mask & OFPPC_NO_RECV_STP) { - /* XXX */ +#define REVALIDATE_BITS (OFPPC_NO_RECV | OFPPC_NO_RECV_STP | OFPPC_NO_FWD) + if (mask & REVALIDATE_BITS) { + port->opp.config ^= mask & REVALIDATE_BITS; + p->need_revalidate = true; } +#undef REVALIDATE_BITS if (mask & OFPPC_NO_FLOOD) { port->opp.config ^= OFPPC_NO_FLOOD; refresh_port_group(p, DP_GROUP_FLOOD); } - if (mask & OFPPC_NO_FWD) { - /* XXX */ - } if (mask & OFPPC_NO_PACKET_IN) { port->opp.config ^= OFPPC_NO_PACKET_IN; } @@ -3226,7 +3233,7 @@ default_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet, if (out_port < 0) { add_output_group_action(actions, DP_GROUP_FLOOD); } else if (out_port != flow->in_port) { - add_output_action(actions, out_port); + odp_actions_add(actions, ODPAT_OUTPUT)->output.port = out_port; } else { /* Drop. */ }