On Tue, Feb 7, 2012 at 5:18 PM,  <[email protected]> wrote:
> That being said, I think the real reason for the issue that your
> running into is that we don't normally have a direct correspondence
> between OpenFlow and kernel actions, particularly for these types of
> TTL actions.  If you look at the IP TTL decrement, there's no
> corresponding kernel TTL decrement, only a set.  So each time that
> userspace encounters a TTL decrement it decrements its copy by 1 (it
> knows the original value because it was part of the original lookup)
> and then generates a set at the end.  I think you could do something
> similar to implement the three remaining MPLS TTL actions using your
> original set MPLS TTL.
>
> [rk] Theoretically I follow this, however, if you can point me to code 
> snippet it would really help.

When processing the OpenFlow action for IP TTL decrement, we just
decrease userspace's copy of the TTL field:

static bool
compose_dec_ttl(struct action_xlate_ctx *ctx)
{
    if (ctx->flow.dl_type != htons(ETH_TYPE_IP) &&
        ctx->flow.dl_type != htons(ETH_TYPE_IPV6)) {
        return false;
    }

    if (ctx->flow.nw_ttl > 1) {
        ctx->flow.nw_ttl--;
        return false;
    } else {
        execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL);

        /* Stop processing for current table. */
        return true;
    }
}

And then when creating the kernel actions we make a set action with
the final value:

static void
commit_set_ipv4_action(const struct flow *flow, struct flow *base,
                     struct ofpbuf *odp_actions)
{
    struct ovs_key_ipv4 ipv4_key;

    if (base->nw_src == flow->nw_src &&
        base->nw_dst == flow->nw_dst &&
        base->nw_tos == flow->nw_tos &&
        base->nw_ttl == flow->nw_ttl &&
        base->nw_frag == flow->nw_frag) {
        return;
    }

    ipv4_key.ipv4_src = base->nw_src = flow->nw_src;
    ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst;
    ipv4_key.ipv4_tos = base->nw_tos = flow->nw_tos;
    ipv4_key.ipv4_ttl = base->nw_ttl = flow->nw_ttl;
    ipv4_key.ipv4_proto = base->nw_proto;
    ipv4_key.ipv4_frag = ovs_to_odp_frag(base->nw_frag);

    commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4,
                      &ipv4_key, sizeof(ipv4_key));
}
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to