static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x) { struct xfrm_state *t = NULL; t = xfrm_state_alloc(); if (!t) goto out; t->id.proto = IPPROTO_IPV6; t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr); memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr)); memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET6; t->props.mode = 1; memcpy(t->props.saddr.a6, x->props.saddr.a6, sizeof(struct in6_addr)); t->type = xfrm_get_type(IPPROTO_IPV6, t->props.family); if (t->type == NULL) goto error; if (t->type->init_state(t, NULL)) goto error; t->km.state = XFRM_STATE_VALID; atomic_set(&t->tunnel_users, 1); out: return t; error: xfrm_state_put(t); goto out; }
/* We always hold one tunnel user reference to indicate a tunnel */ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) { struct xfrm_state *t; t = xfrm_state_alloc(); if (t == NULL) goto out; t->id.proto = IPPROTO_IPIP; t->id.spi = x->props.saddr.a4; t->id.daddr.a4 = x->id.daddr.a4; memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET; t->props.mode = 1; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); if (t->type == NULL) goto error; if (t->type->init_state(t, NULL)) goto error; t->km.state = XFRM_STATE_VALID; atomic_set(&t->tunnel_users, 1); out: return t; error: xfrm_state_put(t); t = NULL; goto out; }