/* Type functions. */
+static struct ofproto_dpif *
+lookup_ofproto_dpif_by_port_name(const char *name)
+{
+ struct ofproto_dpif *ofproto;
+
+ HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
+ if (sset_contains(&ofproto->ports, name)) {
+ return ofproto;
+ }
+ }
+
+ return NULL;
+}
+
static int
type_run(const char *type)
{
/* Check for port changes in the dpif. */
while ((error = dpif_port_poll(backer->dpif, &devname)) == 0) {
- struct ofproto_dpif *ofproto = NULL;
+ struct ofproto_dpif *ofproto;
struct dpif_port port;
/* Don't report on the datapath's device. */
if (!strcmp(devname, dpif_base_name(backer->dpif))) {
- continue;
- }
-
- HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node,
- &all_ofproto_dpifs) {
- if (sset_contains(&ofproto->ports, devname)) {
- break;
- }
+ goto next;
}
+ ofproto = lookup_ofproto_dpif_by_port_name(devname);
if (dpif_port_query_by_name(backer->dpif, devname, &port)) {
/* The port was removed. If we know the datapath,
* report it through poll_set(). If we don't, it may be
sset_add(&ofproto->port_poll_set, devname);
ofproto->port_poll_errno = 0;
}
- dpif_port_destroy(&port);
} else if (!ofproto) {
/* The port was added, but we don't know with which
* ofproto we should associate it. Delete it. */
dpif_port_del(backer->dpif, port.port_no);
}
+ dpif_port_destroy(&port);
+ next:
free(devname);
}
ofproto->port_poll_errno = 0;
SHASH_FOR_EACH_SAFE (node, next, &init_ofp_ports) {
- const struct iface_hint *iface_hint = node->data;
+ struct iface_hint *iface_hint = node->data;
if (!strcmp(iface_hint->br_name, ofproto->up.name)) {
/* Check if the datapath already has this port. */
free(iface_hint->br_name);
free(iface_hint->br_type);
+ free(iface_hint);
shash_delete(&init_ofp_ports, node);
}
}
}
static void
-set_mac_idle_time(struct ofproto *ofproto_, unsigned int idle_time)
+set_mac_table_config(struct ofproto *ofproto_, unsigned int idle_time,
+ size_t max_entries)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
mac_learning_set_idle_time(ofproto->ml, idle_time);
+ mac_learning_set_max_entries(ofproto->ml, max_entries);
}
\f
/* Ports. */
uint32_t odp_port = ofp_port_to_odp_port(ctx->ofproto, ofp_port);
ovs_be16 flow_vlan_tci = ctx->flow.vlan_tci;
uint8_t flow_nw_tos = ctx->flow.nw_tos;
- uint16_t out_port;
-
- if (ofport) {
- struct priority_to_dscp *pdscp;
+ struct priority_to_dscp *pdscp;
+ uint32_t out_port;
- if (ofport->up.pp.config & OFPUTIL_PC_NO_FWD) {
- xlate_report(ctx, "OFPPC_NO_FWD set, skipping output");
- return;
- } else if (check_stp && !stp_forward_in_state(ofport->stp_state)) {
- xlate_report(ctx, "STP not in forwarding state, skipping output");
- return;
- }
+ if (!ofport) {
+ xlate_report(ctx, "Nonexistent output port");
+ return;
+ } else if (ofport->up.pp.config & OFPUTIL_PC_NO_FWD) {
+ xlate_report(ctx, "OFPPC_NO_FWD set, skipping output");
+ return;
+ } else if (check_stp && !stp_forward_in_state(ofport->stp_state)) {
+ xlate_report(ctx, "STP not in forwarding state, skipping output");
+ return;
+ }
- pdscp = get_priority(ofport, ctx->flow.skb_priority);
- if (pdscp) {
- ctx->flow.nw_tos &= ~IP_DSCP_MASK;
- ctx->flow.nw_tos |= pdscp->dscp;
- }
- } else {
- /* We may not have an ofport record for this port, but it doesn't hurt
- * to allow forwarding to it anyhow. Maybe such a port will appear
- * later and we're pre-populating the flow table. */
+ pdscp = get_priority(ofport, ctx->flow.skb_priority);
+ if (pdscp) {
+ ctx->flow.nw_tos &= ~IP_DSCP_MASK;
+ ctx->flow.nw_tos |= pdscp->dscp;
}
out_port = vsp_realdev_to_vlandev(ctx->ofproto, odp_port,
}
if (rule == NULL && may_packet_in) {
- /* TODO:XXX
+ /* XXX
* check if table configuration flags
* OFPTC_TABLE_MISS_CONTROLLER, default.
* OFPTC_TABLE_MISS_CONTINUE,
break;
case OFPACT_PUSH_VLAN:
- /* TODO:XXX 802.1AD(QinQ) */
+ /* XXX 802.1AD(QinQ) */
ctx->flow.vlan_tci = htons(VLAN_CFI);
break;
break;
case OFPACT_CLEAR_ACTIONS:
- /* TODO:XXX
+ /* XXX
* Nothing to do because writa-actions is not supported for now.
* When writa-actions is supported, clear-actions also must
* be supported at the same time.
break;
case OFPACT_GOTO_TABLE: {
- /* TODO:XXX remove recursion */
+ /* XXX remove recursion */
/* It is assumed that goto-table is last action */
struct ofpact_goto_table *ogt = ofpact_get_GOTO_TABLE(a);
assert(ctx->table_id < ogt->table_id);
{
ctx->ofproto = ofproto;
ctx->flow = *flow;
+ memset(&ctx->flow.tunnel, 0, sizeof ctx->flow.tunnel);
ctx->base_flow = ctx->flow;
- memset(&ctx->base_flow.tunnel, 0, sizeof ctx->base_flow.tunnel);
ctx->base_flow.vlan_tci = initial_tci;
ctx->rule = rule;
ctx->packet = packet;
set_flood_vlans,
is_mirror_output_bundle,
forward_bpdu_changed,
- set_mac_idle_time,
+ set_mac_table_config,
set_realdev,
};