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:
Tobias Brunner
2010-09-02 19:04:20 +02:00
parent deea15f04e
commit 952487d689
+132 -61
View File
@@ -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)
{ {