* Set or update reqid for given tunneling interface. * When specified reqid is zero, generate new one. * We are protected by ioctl_sx lock from concurrent id generation. * Also softc would not disappear while we hold ioctl_sx lock. */
| 947 | * Also softc would not disappear while we hold ioctl_sx lock. |
| 948 | */ |
| 949 | static int |
| 950 | ipsec_set_reqid(struct ipsec_softc *sc, uint32_t reqid) |
| 951 | { |
| 952 | struct secasindex *saidx; |
| 953 | |
| 954 | sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); |
| 955 | |
| 956 | if (sc->reqid == reqid && reqid != 0) |
| 957 | return (0); |
| 958 | |
| 959 | if (reqid != 0) { |
| 960 | /* Check that specified reqid doesn't exist */ |
| 961 | if (ipsec_check_reqid(reqid) != 0) |
| 962 | return (EEXIST); |
| 963 | if (sc->reqid != 0) { |
| 964 | CK_LIST_REMOVE(sc, idhash); |
| 965 | IPSEC_WAIT(); |
| 966 | } |
| 967 | sc->reqid = reqid; |
| 968 | CK_LIST_INSERT_HEAD(ipsec_idhash(reqid), sc, idhash); |
| 969 | } else { |
| 970 | /* Generate new reqid */ |
| 971 | if (ipsec_init_reqid(sc) != 0) |
| 972 | return (EEXIST); |
| 973 | } |
| 974 | |
| 975 | /* Tunnel isn't fully configured, just return. */ |
| 976 | if (sc->family == 0) |
| 977 | return (0); |
| 978 | |
| 979 | saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); |
| 980 | KASSERT(saidx != NULL, |
| 981 | ("saidx is NULL, but family is %d", sc->family)); |
| 982 | return (ipsec_set_tunnel(sc, &saidx->src.sa, &saidx->dst.sa, |
| 983 | sc->reqid)); |
| 984 | } |
| 985 | |
| 986 | /* |
| 987 | * Set tunnel endpoints addresses. |
no test coverage detected