I don't know much about l2tp, pipex or npppd.  So I cannot say if
the new logic is correct.  But I guess you have tested that.

The tdb mutex and ref counting looks correct.

> +     struct tdb *tdb, *tdblocal = NULL;

The variable names tdb and tdbp are used very inconsistently within
IPsec.  Don't use both.  I think tdpb and a tdbflow are sufficient.

> +     if (ipsecflowinfo != 0)
> +             ids = ipsp_ids_lookup(ipsecflowinfo);

Can you move that to the place where it is needed?

> +     /*
> +      * Prepare tdb for searching the correct SPD by rn_lookup().
> +      * "tdb_filtemask" of the tdb is used to find the correct SPD when
> +      * multiple policies are overlapped.
> +      */
> +     tdb = tdbp;
> +     if (ipsecflowinfo != 0 && ids != NULL) {
> +             KASSERT(tdbp == NULL);
> +             KASSERT(direction == IPSP_DIRECTION_OUT);
> +             if ((tdblocal = gettdbbyflow(rdomain, direction, &dst,
> +                 IPPROTO_ESP, ids)) != NULL)
> +                     tdb = tdblocal;
> +     }
> +
>       /* Actual SPD lookup. */
> -     if ((rnh = spd_table_get(rdomain)) == NULL ||
> -         (rn = rn_match((caddr_t)&dst, rnh)) == NULL) {
> +     rnh = spd_table_get(rdomain);
> +     if (rnh != NULL) {
> +             if (tdb != NULL)
> +                     rn = rn_lookup((caddr_t)&tdb->tdb_filter,
> +                         (caddr_t)&tdb->tdb_filtermask, rnh);
> +             else
> +                     rn = rn_match((caddr_t)&dst, rnh);
> +     }
> +     tdb_unref(tdblocal);

Perhaps it is easier to understand this way:

        if (ipsecflowinfo != 0) {
                ids = ipsp_ids_lookup(ipsecflowinfo);
                if (ids != NULL)
                        tdbflow = gettdbbyflow(rdomain, direction, &dst,
                            IPPROTO_ESP, ids);
        }

        /* Actual SPD lookup. */
        rnh = spd_table_get(rdomain);
        if (rnh != NULL) {
                if (tdbflow != NULL)
                        rn = rn_lookup((caddr_t)&tdbflow->tdb_filter,
                            (caddr_t)&tdbflow->tdb_filtermask, rnh);
                else if (tdb != NULL)
                        rn = rn_lookup((caddr_t)&tdbp->tdb_filter,
                            (caddr_t)&tdbp->tdb_filtermask, rnh);
                else
                        rn = rn_match((caddr_t)&dst, rnh);
        }
        tdb_unref(tdbflow);

It is hard to say whether the new
rn_lookup(tdbp->tdb_filter/tdbp->tdb_filtermask) changes existing
IPsec behavior for setups without l2tp.  Do we need it there?
I never ran into problems patching the correct policy.

bluhm

Reply via email to