pluto: Migrated raw_eroute to libhydra's kernel interface.
This introduces a new struct to pass the protocol information like spis. Also adapted eroute_connection and the simple calls of raw_eroute to the new signature.
This commit is contained in:
+132
-61
@@ -164,17 +164,20 @@ static void set_text_said(char *text_said, const ip_address *dst,
|
|||||||
|
|
||||||
bool no_klips = FALSE; /* don't actually use KLIPS */
|
bool no_klips = FALSE; /* don't actually use KLIPS */
|
||||||
|
|
||||||
static const struct pfkey_proto_info null_proto_info[2] = {
|
/**
|
||||||
{
|
* Struct to store information about the SAs to install in the kernel
|
||||||
proto: IPPROTO_ESP,
|
*/
|
||||||
encapsulation: ENCAPSULATION_MODE_TRANSPORT,
|
struct kernel_proto_info {
|
||||||
reqid: 0
|
ipsec_mode_t mode;
|
||||||
},
|
u_int32_t esp_spi;
|
||||||
{
|
u_int32_t ah_spi;
|
||||||
proto: 0,
|
u_int32_t reqid;
|
||||||
encapsulation: 0,
|
u_int16_t ipcomp;
|
||||||
reqid: 0
|
u_int16_t cpi;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
static const struct kernel_proto_info null_proto_info = {
|
||||||
|
.mode = MODE_TRANSPORT,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -951,10 +954,10 @@ show_shunt_status(void)
|
|||||||
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
|
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup an IPsec route entry.
|
/**
|
||||||
|
* Setup an IPsec route entry.
|
||||||
* op is one of the ERO_* operators.
|
* op is one of the ERO_* operators.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool raw_eroute(const ip_address *this_host,
|
static bool raw_eroute(const ip_address *this_host,
|
||||||
const ip_subnet *this_client,
|
const ip_subnet *this_client,
|
||||||
const ip_address *that_host,
|
const ip_address *that_host,
|
||||||
@@ -963,12 +966,20 @@ static bool raw_eroute(const ip_address *this_host,
|
|||||||
unsigned int proto,
|
unsigned int proto,
|
||||||
unsigned int satype,
|
unsigned int satype,
|
||||||
unsigned int transport_proto,
|
unsigned int transport_proto,
|
||||||
const struct pfkey_proto_info *proto_info,
|
const struct kernel_proto_info *pi,
|
||||||
time_t use_lifetime,
|
time_t use_lifetime,
|
||||||
unsigned int op,
|
unsigned int op,
|
||||||
const char *opname USED_BY_DEBUG)
|
const char *opname USED_BY_DEBUG)
|
||||||
{
|
{
|
||||||
|
traffic_selector_t *ts_src, *ts_dst;
|
||||||
|
host_t *host_src, *host_dst;
|
||||||
|
policy_type_t type = POLICY_IPSEC;
|
||||||
|
policy_dir_t dir = POLICY_OUT;
|
||||||
|
mark_t mark_none = { 0, 0 };
|
||||||
char text_said[SATOT_BUF];
|
char text_said[SATOT_BUF];
|
||||||
|
bool ok = TRUE, routed = FALSE,
|
||||||
|
deleting = (op & ERO_MASK) == ERO_DELETE,
|
||||||
|
replacing = op & (SADB_X_SAFLAGS_REPLACEFLOW << ERO_FLAG_SHIFT);
|
||||||
|
|
||||||
set_text_said(text_said, that_host, spi, proto);
|
set_text_said(text_said, that_host, spi, proto);
|
||||||
|
|
||||||
@@ -986,9 +997,80 @@ static bool raw_eroute(const ip_address *this_host,
|
|||||||
, text_said, transport_proto);
|
, text_said, transport_proto);
|
||||||
});
|
});
|
||||||
|
|
||||||
return kernel_ops->raw_eroute(this_host, this_client
|
if (satype == SADB_X_SATYPE_INT)
|
||||||
, that_host, that_client, spi, satype, transport_proto, proto_info
|
{
|
||||||
, use_lifetime, op, text_said);
|
switch (ntohl(spi))
|
||||||
|
{
|
||||||
|
case SPI_PASS:
|
||||||
|
type = POLICY_PASS;
|
||||||
|
break;
|
||||||
|
case SPI_DROP:
|
||||||
|
case SPI_REJECT:
|
||||||
|
type = POLICY_DROP;
|
||||||
|
break;
|
||||||
|
case SPI_TRAP:
|
||||||
|
case SPI_TRAPSUBNET:
|
||||||
|
case SPI_HOLD:
|
||||||
|
if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
routed = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op & (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT))
|
||||||
|
{
|
||||||
|
dir = POLICY_IN;
|
||||||
|
}
|
||||||
|
|
||||||
|
host_src = host_create_from_sockaddr((sockaddr_t*)this_host);
|
||||||
|
host_dst = host_create_from_sockaddr((sockaddr_t*)that_host);
|
||||||
|
ts_src = traffic_selector_from_subnet(this_client, transport_proto);
|
||||||
|
ts_dst = traffic_selector_from_subnet(that_client, transport_proto);
|
||||||
|
|
||||||
|
if (deleting || replacing)
|
||||||
|
{
|
||||||
|
hydra->kernel_interface->del_policy(hydra->kernel_interface,
|
||||||
|
ts_src, ts_dst, dir, mark_none, routed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deleting)
|
||||||
|
{
|
||||||
|
/* FIXME: use_lifetime? */
|
||||||
|
ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
|
||||||
|
host_src, host_dst, ts_src, ts_dst, dir, type,
|
||||||
|
pi->esp_spi, pi->ah_spi, pi->reqid, mark_none, pi->mode,
|
||||||
|
pi->ipcomp, pi->cpi, routed) == SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == POLICY_IN)
|
||||||
|
{ /* handle forward policy */
|
||||||
|
dir = POLICY_FWD;
|
||||||
|
if (deleting || replacing)
|
||||||
|
{
|
||||||
|
hydra->kernel_interface->del_policy(hydra->kernel_interface,
|
||||||
|
ts_src, ts_dst, dir, mark_none, routed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deleting && ok &&
|
||||||
|
(pi->mode == MODE_TUNNEL || satype == SADB_X_SATYPE_INT))
|
||||||
|
{
|
||||||
|
/* FIXME: use_lifetime? */
|
||||||
|
ok = hydra->kernel_interface->add_policy(hydra->kernel_interface,
|
||||||
|
host_src, host_dst, ts_src, ts_dst, dir, type,
|
||||||
|
pi->esp_spi, pi->ah_spi, pi->reqid, mark_none, pi->mode,
|
||||||
|
pi->ipcomp, pi->cpi, routed) == SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
host_src->destroy(host_src);
|
||||||
|
host_dst->destroy(host_dst);
|
||||||
|
ts_src->destroy(ts_src);
|
||||||
|
ts_dst->destroy(ts_dst);
|
||||||
|
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test to see if %hold remains */
|
/* test to see if %hold remains */
|
||||||
@@ -1034,10 +1116,10 @@ bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
|
|||||||
/* is there already a broad host-to-host bare shunt? */
|
/* is there already a broad host-to-host bare shunt? */
|
||||||
if (bs_pp == NULL)
|
if (bs_pp == NULL)
|
||||||
{
|
{
|
||||||
if (raw_eroute(null_host, &this_broad_client, null_host, &that_broad_client
|
if (raw_eroute(null_host, &this_broad_client, null_host,
|
||||||
, htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
|
&that_broad_client, htonl(shunt_spi), SA_INT,
|
||||||
, 0, null_proto_info
|
SADB_X_SATYPE_INT, 0, &null_proto_info,
|
||||||
, SHUNT_PATIENCE, ERO_ADD, why))
|
SHUNT_PATIENCE, ERO_ADD, why))
|
||||||
{
|
{
|
||||||
struct bare_shunt *bs = malloc_thing(struct bare_shunt);
|
struct bare_shunt *bs = malloc_thing(struct bare_shunt);
|
||||||
|
|
||||||
@@ -1059,10 +1141,9 @@ bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
|
|||||||
shunt_spi = SPI_HOLD;
|
shunt_spi = SPI_HOLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (raw_eroute(null_host, &this_client, null_host, &that_client
|
if (raw_eroute(null_host, &this_client, null_host, &that_client,
|
||||||
, htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT
|
htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT, transport_proto,
|
||||||
, transport_proto, null_proto_info
|
&null_proto_info, SHUNT_PATIENCE, ERO_DELETE, why))
|
||||||
, SHUNT_PATIENCE, ERO_DELETE, why))
|
|
||||||
{
|
{
|
||||||
struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
|
struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
|
||||||
, transport_proto);
|
, transport_proto);
|
||||||
@@ -1079,7 +1160,7 @@ bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
|
|||||||
|
|
||||||
static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
|
static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
|
||||||
unsigned int proto, unsigned int satype,
|
unsigned int proto, unsigned int satype,
|
||||||
const struct pfkey_proto_info *proto_info,
|
const struct kernel_proto_info *proto_info,
|
||||||
unsigned int op, const char *opname)
|
unsigned int op, const char *opname)
|
||||||
{
|
{
|
||||||
const ip_address *peer = &sr->that.host_addr;
|
const ip_address *peer = &sr->that.host_addr;
|
||||||
@@ -1092,11 +1173,9 @@ static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
|
|||||||
{
|
{
|
||||||
peer = aftoinfo(addrtypeof(peer))->any;
|
peer = aftoinfo(addrtypeof(peer))->any;
|
||||||
}
|
}
|
||||||
return raw_eroute(&sr->this.host_addr, &sr->this.client
|
return raw_eroute(&sr->this.host_addr, &sr->this.client, peer,
|
||||||
, peer
|
&sr->that.client, spi, proto, satype, sr->this.protocol,
|
||||||
, &sr->that.client
|
proto_info, 0, op, buf2);
|
||||||
, spi, proto, satype
|
|
||||||
, sr->this.protocol, proto_info, 0, op, buf2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign a bare hold to a connection */
|
/* assign a bare hold to a connection */
|
||||||
@@ -1139,18 +1218,17 @@ bool assign_hold(connection_t *c USED_BY_DEBUG, struct spd_route *sr,
|
|||||||
if (rn != ro)
|
if (rn != ro)
|
||||||
{
|
{
|
||||||
if (erouted(ro)
|
if (erouted(ro)
|
||||||
? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
|
? !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT,
|
||||||
, null_proto_info
|
&null_proto_info, ERO_REPLACE,
|
||||||
, ERO_REPLACE, "replace %trap with broad %hold")
|
"replace %trap with broad %hold")
|
||||||
: !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
|
: !eroute_connection(sr, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT,
|
||||||
, null_proto_info
|
&null_proto_info, ERO_ADD, "add broad %hold"))
|
||||||
, ERO_ADD, "add broad %hold"))
|
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE
|
if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE,
|
||||||
, transport_proto, "delete narrow %hold"))
|
transport_proto, "delete narrow %hold"))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -1344,17 +1422,13 @@ static bool shunt_eroute(connection_t *c, struct spd_route *sr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = TRUE;
|
ok = raw_eroute(&c->spd.that.host_addr, &c->spd.that.client,
|
||||||
if (kernel_ops->inbound_eroute)
|
&c->spd.this.host_addr, &c->spd.this.client, htonl(spi),
|
||||||
{
|
SA_INT, SADB_X_SATYPE_INT, 0, &null_proto_info, 0,
|
||||||
ok = raw_eroute(&c->spd.that.host_addr, &c->spd.that.client
|
op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), opname);
|
||||||
, &c->spd.this.host_addr, &c->spd.this.client
|
|
||||||
, htonl(spi), SA_INT, SADB_X_SATYPE_INT
|
return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT,
|
||||||
, 0, null_proto_info, 0
|
&null_proto_info, op, opname) && ok;
|
||||||
, op | (SADB_X_SAFLAGS_INFLOW << ERO_FLAG_SHIFT), opname);
|
|
||||||
}
|
|
||||||
return eroute_connection(sr, htonl(spi), SA_INT, SADB_X_SATYPE_INT
|
|
||||||
, null_proto_info, op, opname) && ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool del_spi(ipsec_spi_t spi, int proto,
|
static bool del_spi(ipsec_spi_t spi, int proto,
|
||||||
@@ -2370,17 +2444,14 @@ bool route_and_eroute(connection_t *c USED_BY_KLIPS,
|
|||||||
*/
|
*/
|
||||||
struct bare_shunt *bs = *bspp;
|
struct bare_shunt *bs = *bspp;
|
||||||
|
|
||||||
(void) raw_eroute(&bs->said.dst /* should be useless */
|
(void) raw_eroute(&bs->said.dst, /* should be useless */
|
||||||
, &bs->ours
|
&bs->ours,
|
||||||
, &bs->said.dst /* should be useless */
|
&bs->said.dst, /* should be useless */
|
||||||
, &bs->his
|
&bs->his,
|
||||||
, bs->said.spi /* network order */
|
bs->said.spi, /* network order */
|
||||||
, SA_INT
|
SA_INT, SADB_X_SATYPE_INT, 0,
|
||||||
, SADB_X_SATYPE_INT
|
&null_proto_info, SHUNT_PATIENCE,
|
||||||
, 0
|
ERO_REPLACE, "restore");
|
||||||
, null_proto_info
|
|
||||||
, SHUNT_PATIENCE
|
|
||||||
, ERO_REPLACE, "restore");
|
|
||||||
}
|
}
|
||||||
else if (ero != NULL)
|
else if (ero != NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user