static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
 {
+       unsigned int dir;
        int err;
        struct sadb_x_policy *pol;
        struct xfrm_policy *xp;
        if ((pol = ext_hdrs[SADB_X_EXT_POLICY-1]) == NULL)
                return -EINVAL;
 
-       xp = xfrm_policy_byid(0, pol->sadb_x_policy_id,
+       dir = xfrm_policy_id2dir(pol->sadb_x_policy_id);
+       if (dir >= XFRM_POLICY_MAX)
+               return -EINVAL;
+
+       xp = xfrm_policy_byid(dir, pol->sadb_x_policy_id,
                              hdr->sadb_msg_type == SADB_X_SPDDELETE2);
        if (xp == NULL)
                return -ENOENT;
        if (hdr->sadb_msg_type == SADB_X_SPDDELETE2) {
                c.data.byid = 1;
                c.event = XFRM_MSG_DELPOLICY;
-               km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
+               km_policy_notify(xp, dir, &c);
        } else {
-               err = key_pol_get_resp(sk, xp, hdr, pol->sadb_x_policy_dir-1);
+               err = key_pol_get_resp(sk, xp, hdr, dir);
        }
 
        xfrm_pol_put(xp);
 
        if (xp->dead)
                goto out;
 
-       dir = xp->index & 7;
+       dir = xfrm_policy_id2dir(xp->index);
 
        if (xp->lft.hard_add_expires_seconds) {
                long tmo = xp->lft.hard_add_expires_seconds +
        struct xfrm_policy *pol, **p;
 
        write_lock_bh(&xfrm_policy_lock);
-       for (p = &xfrm_policy_list[id & 7]; (pol=*p)!=NULL; p = &pol->next) {
+       for (p = &xfrm_policy_list[dir]; (pol=*p)!=NULL; p = &pol->next) {
                if (pol->index == id) {
                        xfrm_pol_hold(pol);
                        if (delete)