[ovs-dev] [RFC recirc fix] recirculation: Map recirc_id to ofproto_dpif.
Alex Wang
alexw at nicira.com
Sun Dec 21 01:24:10 UTC 2014
Thx Andy for the review,
Please see my reply below,
> + * When recirc_id is set in 'flow', checks whether the ofproto_dpif that
> > + * corresponds to the recirc_id is same as the receiving bridge. If
> they are
> > + * the same, uses the 'ofproto' and keeps the 'ofp_in_port' as assigned.
> > + * Otherwise, uses the 'recirc_ofproto' that owns recirc_id and assigns
> > + * OFPP_NONE to 'ofp_in_port'. Doing this is in that, for the latter
> case,
> > + * the rules that match the recirculated packets are installed only to
> the
> > + * 'recirc_ofproto', and using OFPP_NONE avoids the case where the
> in_port is
> > + * taken or is non-exist.
> It is probably worth noting that post recirculation flow (with a non
> zero recirc_id) should not be allowed to cross a patch port.
>
Sure, I'll mention this,
> > + if (recirc_ofproto != ofproto) {
> > + *ofp_in_port = OFPP_NONE;
> > + ofproto = recirc_ofproto;
> > + }
> > + }
> Would it make sense to move the logic above into xlate_lookup_ofproto_ ?
>
Yes, I'll put it inside xlate_lookup_ofproto_(), since both are for getting
the
ofproto,
> > +static void
> > +dpif_backer_recirc_clear_ofproto(struct dpif_backer *backer,
> > + struct ofproto_dpif *ofproto)
> > +{
> > + struct dpif_backer_recirc_node *node;
> > +
> > + ovs_mutex_lock(&backer->recirc_mutex);
> > + CMAP_FOR_EACH (node, cmap_node, &backer->recirc_map) {
> > + if (node->ofproto == ofproto) {
> > + cmap_remove(&backer->recirc_map, &node->cmap_node,
> > + node->recirc_id);
>
> This is really an error condition, right? Before a ofproto is
> removed, all resources
> including recirc id should already be freed. On the flip side, if
> this code actually
> found any mapping remaining in cmap, the recirc_id is then leaked.
>
Makes sense, I'll put a warning there,
> > uint32_t
> > ofproto_dpif_alloc_recirc_id(struct ofproto_dpif *ofproto)
> > {
> > struct dpif_backer *backer = ofproto->backer;
> > + struct dpif_backer_recirc_node *node = xmalloc(sizeof *node);
> > + uint32_t recirc_id = recirc_id_alloc(backer->rid_pool);
> >
> > - return recirc_id_alloc(backer->rid_pool);
> recirc_id == 0 indicate failure of allocating the id (i.e. out of id
> pool). We may not want to add it
> to cmap in this case.
>
Thx for pointing it out, I'll add a check,
> > + node = CONTAINER_OF(cmap_find(&backer->recirc_map, recirc_id),
> > + struct dpif_backer_recirc_node, cmap_node);
> > + if (node) {
> > + ovs_mutex_lock(&backer->recirc_mutex);
> > + cmap_remove(&backer->recirc_map, &node->cmap_node,
> node->recirc_id);
> > + recirc_id_free(backer->rid_pool, node->recirc_id);
> The locking looks strange. recirc_id_alloc/free uses its own locking.
> There is really no need
> to call it within the recirc_mutex lock. The alloc() call above does
> it outside. May be we can
> drop id_pool lock and only use recirc_mutex lock.
>
I'll move recirc_id_alloc/free() outside the critical section,
I think we still need to id_pool lock, since other user of the module
may need it,
> > + set interface p1 type=dummy
> options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
> > + set interface p2 type=dummy
> options:pstream=punix:$OVS_RUNDIR/p2.sock ofport_request=2 -- \
> > + add-br br1 -- \
> > + set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
> > + set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
> > + fail-mode=standalone -- \
> > + add-bond br1 bond1 p3 p4 bond_mode=balance-tcp lacp=active \
> > + other-config:lacp-time=fast
> other-config:bond-rebalance-interval=0 -- \
> > + set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock
> ofport_request=3 -- \
> > + set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock
> ofport_request=4 -- \
> > + add-port br1 br1- -- set interface br1- type=patch options:peer=br1+
> ofport_request=100 -- \
> > + set port br1- tag=1 -- \
> > + add-br br-int -- \
> > + set bridge br-int other-config:hwaddr=aa:77:aa:77:00:00 -- \
> > + set bridge br-int datapath-type=dummy other-config:datapath-id=1235 \
> > + fail-mode=secure -- \
> > + add-port br-int br1+ -- set interface br1+ type=patch
> options:peer=br1- ofport_request=101 -- \
> > + add-port br-int p5 -- set interface p5 ofport_request=5 type=dummy
> > +])
> > +AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
> > +])
> > +
> > +# The dl_vlan flow should not be ever matched,
> > +# since recirculation should not change the flow handling.
> > +AT_DATA([flows.txt], [dnl
> > +table=0 priority=1 in_port=5 actions=output(101)
> According to the commit comment, should there be a push vlan action as
> well ?
>
I tag the patch port, which is equivalent to setting the vlan. I agree
this is
very unclear, I'll add a vlan action explicitly!
> + set port br1- tag=1 -- \
More information about the dev
mailing list