pluto: Removed bare shunt table.

This commit is contained in:
Tobias Brunner
2010-09-02 19:04:24 +02:00
parent b8bf01ddee
commit d499bdf393
4 changed files with 8 additions and 339 deletions
-40
View File
@@ -2146,25 +2146,6 @@ static void cannot_oppo(connection_t *c, struct find_oppo_bundle *b, err_t ugh)
}
return;
}
if (b->held)
{
/* Replace HOLD with b->failure_shunt.
* If no b->failure_shunt specified, use SPI_PASS -- THIS MAY CHANGE.
*/
if (b->failure_shunt == 0)
{
DBG(DBG_OPPO, DBG_log("no explicit failure shunt for %s to %s; installing %%pass"
, ocb, pcb));
}
(void) replace_bare_shunt(&b->our_client, &b->peer_client
, b->policy_prio
, b->failure_shunt
, b->failure_shunt != 0
, b->transport_proto
, ugh);
}
}
static void initiate_opportunistic_body(struct find_oppo_bundle *b
@@ -2201,14 +2182,6 @@ static void continue_oppo(struct adns_continuation *acr, err_t ugh)
*/
whack_log_fd = whackfd;
/* Discover and record whether %hold has gone away.
* This could have happened while we were awaiting DNS.
* We must check BEFORE any call to cannot_oppo.
*/
if (was_held)
cr->b.held = has_bare_hold(&cr->b.our_client, &cr->b.peer_client
, cr->b.transport_proto);
#ifdef DEBUG
/* if we're going to ignore the error, at least note it in debugging log */
if (cr->b.failure_ok && ugh)
@@ -2810,19 +2783,6 @@ static void initiate_opportunistic_body(struct find_oppo_bundle *b,
"no suitable connection for opportunism "
"between %s and %s with %Y as peer",
ocb, pcb, ac->gateways_from_dns->gw_id);
if (b->held)
{
/* Replace HOLD with PASS.
* The type of replacement *ought* to be
* specified by policy.
*/
(void) replace_bare_shunt(&b->our_client, &b->peer_client
, BOTTOM_PRIO
, SPI_PASS /* fail into PASS */
, TRUE, b->transport_proto
, "no suitable connection");
}
}
else
{
+8 -286
View File
@@ -75,65 +75,6 @@ bool can_do_IPcomp = TRUE; /* can system actually perform IPCOMP? */
#define routes_agree(c, d) ((c)->interface == (d)->interface \
&& sameaddr(&(c)->spd.this.host_nexthop, &(d)->spd.this.host_nexthop))
/* bare (connectionless) shunt (eroute) table
*
* Bare shunts are those that don't "belong" to a connection.
* This happens because some %trapped traffic hasn't yet or cannot be
* assigned to a connection. The usual reason is that we cannot discover
* the peer SG. Another is that even when the peer has been discovered,
* it may be that no connection matches all the particulars.
* We record them so that, with scanning, we can discover
* which %holds are news and which others should expire.
*/
#define SHUNT_SCAN_INTERVAL (60 * 2) /* time between scans of eroutes */
/* SHUNT_PATIENCE only has resolution down to a multiple of the sample rate,
* SHUNT_SCAN_INTERVAL.
* By making SHUNT_PATIENCE an odd multiple of half of SHUNT_SCAN_INTERVAL,
* we minimize the effects of jitter.
*/
#define SHUNT_PATIENCE (SHUNT_SCAN_INTERVAL * 15 / 2) /* inactivity timeout */
struct bare_shunt {
policy_prio_t policy_prio;
ip_subnet ours;
ip_subnet his;
ip_said said;
int transport_proto;
unsigned long count;
time_t last_activity;
char *why;
struct bare_shunt *next;
};
static struct bare_shunt *bare_shunts = NULL;
#ifdef DEBUG
static void DBG_bare_shunt(const char *op, const struct bare_shunt *bs)
{
DBG(DBG_KERNEL,
{
int ourport = ntohs(portof(&(bs)->ours.addr));
int hisport = ntohs(portof(&(bs)->his.addr));
char ourst[SUBNETTOT_BUF];
char hist[SUBNETTOT_BUF];
char sat[SATOT_BUF];
char prio[POLICY_PRIO_BUF];
subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
subnettot(&(bs)->his, 0, hist, sizeof(hist));
satot(&(bs)->said, 0, sat, sizeof(sat));
fmt_policy_prio(bs->policy_prio, prio);
DBG_log("%s bare shunt %p %s:%d -> %s:%d => %s:%d %s %s"
, op, (const void *)(bs), ourst, ourport, hist, hisport
, sat, (bs)->transport_proto, prio, (bs)->why);
});
}
#else /* !DEBUG */
#define DBG_bare_shunt(op, bs) {}
#endif /* !DEBUG */
/* forward declaration */
static bool shunt_eroute(connection_t *c, struct spd_route *sr,
enum routing_t rt_kind, unsigned int op,
@@ -186,41 +127,13 @@ void record_and_initiate_opportunistic(const ip_subnet *ours,
const ip_subnet *his,
int transport_proto, const char *why)
{
ip_address src, dst;
passert(samesubnettype(ours, his));
/* Add to bare shunt list.
* We need to do this because the shunt was installed by KLIPS
* which can't do this itself.
*/
{
struct bare_shunt *bs = malloc_thing(struct bare_shunt);
bs->why = clone_str(why);
bs->ours = *ours;
bs->his = *his;
bs->transport_proto = transport_proto;
bs->policy_prio = BOTTOM_PRIO;
bs->said.proto = SA_INT;
bs->said.spi = htonl(SPI_HOLD);
bs->said.dst = *aftoinfo(subnettypeof(ours))->any;
bs->count = 0;
bs->last_activity = now();
bs->next = bare_shunts;
bare_shunts = bs;
DBG_bare_shunt("add", bs);
}
/* actually initiate opportunism */
{
ip_address src, dst;
networkof(ours, &src);
networkof(his, &dst);
initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
}
networkof(ours, &src);
networkof(his, &dst);
initiate_opportunistic(&src, &dst, transport_proto, TRUE, NULL_FD);
}
/* Generate Unique SPI numbers.
@@ -818,76 +731,6 @@ static void set_text_said(char *text_said, const ip_address *dst,
satot(&said, 0, text_said, SATOT_BUF);
}
/* find an entry in the bare_shunt table.
* Trick: return a pointer to the pointer to the entry;
* this allows the entry to be deleted.
*/
static struct bare_shunt** bare_shunt_ptr(const ip_subnet *ours,
const ip_subnet *his,
int transport_proto)
{
struct bare_shunt *p, **pp;
for (pp = &bare_shunts; (p = *pp) != NULL; pp = &p->next)
{
if (samesubnet(ours, &p->ours)
&& samesubnet(his, &p->his)
&& transport_proto == p->transport_proto
&& portof(&ours->addr) == portof(&p->ours.addr)
&& portof(&his->addr) == portof(&p->his.addr))
return pp;
}
return NULL;
}
/* free a bare_shunt entry, given a pointer to the pointer */
static void free_bare_shunt(struct bare_shunt **pp)
{
if (pp == NULL)
{
DBG(DBG_CONTROL,
DBG_log("delete bare shunt: null pointer")
)
}
else
{
struct bare_shunt *p = *pp;
*pp = p->next;
DBG_bare_shunt("delete", p);
free(p->why);
free(p);
}
}
void
show_shunt_status(void)
{
struct bare_shunt *bs;
for (bs = bare_shunts; bs != NULL; bs = bs->next)
{
/* Print interesting fields. Ignore count and last_active. */
int ourport = ntohs(portof(&bs->ours.addr));
int hisport = ntohs(portof(&bs->his.addr));
char ourst[SUBNETTOT_BUF];
char hist[SUBNETTOT_BUF];
char sat[SATOT_BUF];
char prio[POLICY_PRIO_BUF];
subnettot(&(bs)->ours, 0, ourst, sizeof(ourst));
subnettot(&(bs)->his, 0, hist, sizeof(hist));
satot(&(bs)->said, 0, sat, sizeof(sat));
fmt_policy_prio(bs->policy_prio, prio);
whack_log(RC_COMMENT, "%s:%d -> %s:%d => %s:%d %s %s"
, ourst, ourport, hist, hisport, sat, bs->transport_proto
, prio, bs->why);
}
if (bare_shunts != NULL)
whack_log(RC_COMMENT, BLANK_FORMAT); /* spacer */
}
/**
* Setup an IPsec route entry.
@@ -1006,91 +849,6 @@ static bool raw_eroute(const ip_address *this_host,
return ok;
}
/* test to see if %hold remains */
bool has_bare_hold(const ip_address *src, const ip_address *dst,
int transport_proto)
{
ip_subnet this_client, that_client;
struct bare_shunt **bspp;
passert(addrtypeof(src) == addrtypeof(dst));
happy(addrtosubnet(src, &this_client));
happy(addrtosubnet(dst, &that_client));
bspp = bare_shunt_ptr(&this_client, &that_client, transport_proto);
return bspp != NULL
&& (*bspp)->said.proto == SA_INT && (*bspp)->said.spi == htonl(SPI_HOLD);
}
/* Replace (or delete) a shunt that is in the bare_shunts table.
* Issues the PF_KEY commands and updates the bare_shunts table.
*/
bool replace_bare_shunt(const ip_address *src, const ip_address *dst,
policy_prio_t policy_prio, ipsec_spi_t shunt_spi,
bool repl, unsigned int transport_proto, const char *why)
{
ip_subnet this_client, that_client;
ip_subnet this_broad_client, that_broad_client;
const ip_address *null_host = aftoinfo(addrtypeof(src))->any;
passert(addrtypeof(src) == addrtypeof(dst));
happy(addrtosubnet(src, &this_client));
happy(addrtosubnet(dst, &that_client));
this_broad_client = this_client;
that_broad_client = that_client;
setportof(0, &this_broad_client.addr);
setportof(0, &that_broad_client.addr);
if (repl)
{
struct bare_shunt **bs_pp = bare_shunt_ptr(&this_broad_client
, &that_broad_client, 0);
/* is there already a broad host-to-host bare shunt? */
if (bs_pp == NULL)
{
if (raw_eroute(null_host, &this_broad_client, null_host,
&that_broad_client, htonl(shunt_spi), SA_INT,
SADB_X_SATYPE_INT, 0, &null_ipsec_sa,
SHUNT_PATIENCE, ERO_ADD, why))
{
struct bare_shunt *bs = malloc_thing(struct bare_shunt);
bs->ours = this_broad_client;
bs->his = that_broad_client;
bs->transport_proto = 0;
bs->said.proto = SA_INT;
bs->why = clone_str(why);
bs->policy_prio = policy_prio;
bs->said.spi = htonl(shunt_spi);
bs->said.dst = *null_host;
bs->count = 0;
bs->last_activity = now();
bs->next = bare_shunts;
bare_shunts = bs;
DBG_bare_shunt("add", bs);
}
}
shunt_spi = SPI_HOLD;
}
if (raw_eroute(null_host, &this_client, null_host, &that_client,
htonl(shunt_spi), SA_INT, SADB_X_SATYPE_INT, transport_proto,
&null_ipsec_sa, SHUNT_PATIENCE, ERO_DELETE, why))
{
struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client
, transport_proto);
/* delete bare eroute */
free_bare_shunt(bs_pp);
return TRUE;
}
else
{
return FALSE;
}
}
static bool eroute_connection(struct spd_route *sr, ipsec_spi_t spi,
unsigned int proto, unsigned int satype,
ipsec_sa_cfg_t *sa, unsigned int op,
@@ -1141,12 +899,11 @@ bool assign_hold(connection_t *c USED_BY_DEBUG, struct spd_route *sr,
break;
}
/* we need a broad %hold, not the narrow one.
/* We need a broad %hold
* First we ensure that there is a broad %hold.
* There may already be one (race condition): no need to create one.
* There may already be a %trap: replace it.
* There may not be any broad eroute: add %hold.
* Once the broad %hold is in place, delete the narrow one.
*/
if (rn != ro)
{
@@ -1160,11 +917,6 @@ bool assign_hold(connection_t *c USED_BY_DEBUG, struct spd_route *sr,
return FALSE;
}
}
if (!replace_bare_shunt(src, dst, BOTTOM_PRIO, SPI_HOLD, FALSE,
transport_proto, "delete narrow %hold"))
{
return FALSE;
}
sr->routing = rn;
return TRUE;
}
@@ -1920,7 +1672,6 @@ bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
, route_installed = FALSE;
connection_t *ero_top;
struct bare_shunt **bspp;
DBG(DBG_CONTROLMORE,
DBG_log("route_and_eroute with c: %s (next: %s) ero:%s esr:{%p} ro:%s rosr:{%p} and state: %lu"
@@ -1947,15 +1698,9 @@ bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
break;
#endif
bspp = (ero == NULL)
? bare_shunt_ptr(&sr->this.client, &sr->that.client, sr->this.protocol)
: NULL;
/* install the eroute */
passert(bspp == NULL || ero == NULL); /* only one non-NULL */
if (bspp != NULL || ero != NULL)
if (ero != NULL)
{
/* We're replacing an eroute */
@@ -1981,7 +1726,6 @@ bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
&& samesubnet(&esr->that.client, &sr->that.client));
}
#endif
/* remember to free bspp iff we make it out of here alive */
}
else
{
@@ -2073,11 +1817,7 @@ bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
{
/* Success! */
if (bspp != NULL)
{
free_bare_shunt(bspp);
}
else if (ero != NULL && ero != c)
if (ero != NULL && ero != c)
{
/* check if ero is an ancestor of c. */
connection_t *ero2;
@@ -2131,25 +1871,7 @@ bool route_and_eroute(connection_t *c, struct spd_route *sr, struct state *st)
* Since there is nothing much to be done if the restoration
* fails, ignore success or failure.
*/
if (bspp != NULL)
{
/* Restore old bare_shunt.
* I don't think that this case is very likely.
* Normally a bare shunt would have been assigned
* to a connection before we've gotten this far.
*/
struct bare_shunt *bs = *bspp;
(void) raw_eroute(&bs->said.dst, /* should be useless */
&bs->ours,
&bs->said.dst, /* should be useless */
&bs->his,
bs->said.spi, /* network order */
SA_INT, SADB_X_SATYPE_INT, 0,
&null_ipsec_sa, SHUNT_PATIENCE,
ERO_REPLACE, "restore");
}
else if (ero != NULL)
if (ero != NULL)
{
/* restore ero's former glory */
if (esr->eroute_owner == SOS_NOBODY)
-12
View File
@@ -73,8 +73,6 @@ struct kernel_sa {
const char *text_said;
};
extern void show_shunt_status(void);
/* A netlink header defines EM_MAXRELSPIS, the max number of SAs in a group.
* Is there a PF_KEY equivalent?
*/
@@ -93,16 +91,6 @@ extern void kernel_finalize(void);
extern bool trap_connection(struct connection *c);
extern void unroute_connection(struct connection *c);
extern bool has_bare_hold(const ip_address *src, const ip_address *dst
, int transport_proto);
extern bool replace_bare_shunt(const ip_address *src, const ip_address *dst
, policy_prio_t policy_prio
, ipsec_spi_t shunt_spi /* in host order! */
, bool repl
, unsigned int transport_proto
, const char *why);
extern bool assign_hold(struct connection *c
, struct spd_route *sr
, int transport_proto
-1
View File
@@ -862,7 +862,6 @@ void show_status(bool all, const char *name)
}
show_connections_status(all, name);
show_states_status(all, name);
show_shunt_status();
}
/* ip_str: a simple to use variant of addrtot.