static int set_bfd(struct ofport *, const struct smap *);
static int set_cfm(struct ofport *, const struct cfm_settings *);
static void ofport_clear_priorities(struct ofport_dpif *);
+static void ofport_update_peer(struct ofport_dpif *);
static void run_fast_rl(void);
struct dpif_completion {
struct oftable *table;
int i;
+ ofproto->backer->need_revalidate = REV_RECONFIGURE;
hmap_remove(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node);
complete_operations(ofproto);
port->stp_port = NULL;
port->stp_state = STP_DISABLED;
port->tnl_port = NULL;
+ port->peer = NULL;
hmap_init(&port->priorities);
port->realdev_ofp_port = 0;
port->vlandev_vid = 0;
* to be "internal" to the switch as a whole, and therefore not an
* candidate for counter polling. */
port->odp_port = OVSP_NONE;
+ ofport_update_peer(port);
return 0;
}
ofproto->backer->need_revalidate = REV_RECONFIGURE;
}
+ if (port->peer) {
+ port->peer->peer = NULL;
+ port->peer = NULL;
+ }
+
if (port->odp_port != OVSP_NONE && !port->tnl_port) {
hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node);
}
if (port->cfm) {
cfm_set_netdev(port->cfm, port->up.netdev);
}
+
+ if (port->tnl_port && tnl_port_reconfigure(&port->up, port->odp_port,
+ &port->tnl_port)) {
+ ofproto_dpif_cast(port->up.ofproto)->backer->need_revalidate = true;
+ }
+
+ ofport_update_peer(port);
}
static void
ofproto_port->ofp_port = odp_port_to_ofp_port(ofproto, dpif_port->port_no);
}
-struct ofport_dpif *
-ofport_get_peer(const struct ofport_dpif *ofport_dpif)
+static void
+ofport_update_peer(struct ofport_dpif *ofport)
{
const struct ofproto_dpif *ofproto;
- const struct dpif_backer *backer;
- const char *peer;
+ struct dpif_backer *backer;
+ const char *peer_name;
- peer = netdev_vport_patch_peer(ofport_dpif->up.netdev);
- if (!peer) {
- return NULL;
+ if (!netdev_vport_is_patch(ofport->up.netdev)) {
+ return;
+ }
+
+ backer = ofproto_dpif_cast(ofport->up.ofproto)->backer;
+ backer->need_revalidate = true;
+
+ if (ofport->peer) {
+ ofport->peer->peer = NULL;
+ ofport->peer = NULL;
+ }
+
+ peer_name = netdev_vport_patch_peer(ofport->up.netdev);
+ if (!peer_name) {
+ return;
}
- backer = ofproto_dpif_cast(ofport_dpif->up.ofproto)->backer;
HMAP_FOR_EACH (ofproto, all_ofproto_dpifs_node, &all_ofproto_dpifs) {
- struct ofport *ofport;
+ struct ofport *peer_ofport;
+ struct ofport_dpif *peer;
+ const char *peer_peer;
if (ofproto->backer != backer) {
continue;
}
- ofport = shash_find_data(&ofproto->up.port_by_name, peer);
- if (ofport) {
- return ofport_dpif_cast(ofport);
+ peer_ofport = shash_find_data(&ofproto->up.port_by_name, peer_name);
+ if (!peer_ofport) {
+ continue;
}
+
+ peer = ofport_dpif_cast(peer_ofport);
+ peer_peer = netdev_vport_patch_peer(peer->up.netdev);
+ if (peer_peer && !strcmp(netdev_get_name(ofport->up.netdev),
+ peer_peer)) {
+ ofport->peer = peer;
+ ofport->peer->peer = ofport;
+ }
+
+ return;
}
- return NULL;
}
static void
port_run_fast(ofport);
- if (ofport->tnl_port
- && tnl_port_reconfigure(&ofport->up, ofport->odp_port,
- &ofport->tnl_port)) {
- ofproto_dpif_cast(ofport->up.ofproto)->backer->need_revalidate = true;
- }
-
if (ofport->cfm) {
int cfm_opup = cfm_get_opup(ofport->cfm);
put->flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
put->key = miss->key;
put->key_len = miss->key_len;
+ put->mask = NULL;
+ put->mask_len = 0;
if (want_path == SF_FAST_PATH) {
put->actions = facet->xout.odp_actions.data;
put->actions_len = facet->xout.odp_actions.size;
hmap_insert(&backer->drop_keys, &drop_key->hmap_node,
hash_bytes(drop_key->key, drop_key->key_len, 0));
dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
- drop_key->key, drop_key->key_len, NULL, 0, NULL);
+ drop_key->key, drop_key->key_len,
+ NULL, 0, NULL, 0, NULL);
}
continue;
}
size_t key_len;
dpif_flow_dump_start(&dump, backer->dpif);
- while (dpif_flow_dump_next(&dump, &key, &key_len, NULL, NULL, &stats)) {
+ while (dpif_flow_dump_next(&dump, &key, &key_len,
+ NULL, NULL, NULL, NULL, &stats)) {
struct subfacet *subfacet;
uint32_t key_hash;
&actions, &actions_len);
}
- ret = dpif_flow_put(subfacet->backer->dpif, flags, subfacet->key,
- subfacet->key_len, actions, actions_len, stats);
+ ret = dpif_flow_put(ofproto->backer->dpif, flags, subfacet->key,
+ subfacet->key_len, NULL, 0,
+ actions, actions_len, stats);
if (stats) {
subfacet_reset_dp_stats(subfacet, stats);
return NULL;
}
+ if (wc) {
+ wc->masks.nw_frag |= FLOW_NW_FRAG_MASK;
+ }
+
cls = &ofproto->up.tables[table_id].cls;
frag = (flow->nw_frag & FLOW_NW_FRAG_ANY) != 0;
if (frag && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) {
if (netflow_options) {
if (!ofproto->netflow) {
ofproto->netflow = netflow_create();
+ ofproto->backer->need_revalidate = REV_RECONFIGURE;
}
return netflow_set_options(ofproto->netflow, netflow_options);
- } else {
+ } else if (ofproto->netflow) {
+ ofproto->backer->need_revalidate = REV_RECONFIGURE;
netflow_destroy(ofproto->netflow);
ofproto->netflow = NULL;
- return 0;
}
+
+ return 0;
}
static void
* bridge is specified. If function odp_flow_key_from_string()
* returns 0, the flow is a odp_flow. If function
* parse_ofp_exact_flow() returns 0, the flow is a br_flow. */
- if (!odp_flow_key_from_string(argv[argc - 1], NULL, &odp_key)) {
+ if (!odp_flow_from_string(argv[argc - 1], NULL, &odp_key, NULL)) {
/* If the odp_flow is the second argument,
* the datapath name is the first argument. */
if (argc == 3) {