1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/* route connections, for libreswan
*
* Copyright (C) 2023 Andrew Cagney
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*/
#include <stdbool.h>
#include "whack_route.h"
#include "connections.h"
#include "server.h" /* for listen; */
#include "show.h"
#include "log.h"
#include "visit_connection.h"
#include "ipsec_interface.h"
static unsigned maybe_route_connection(struct connection *c)
{
if (is_instance(c)) {
pdbg(c->logger, "instances are not routed");
return 0; /* not counted */
}
if (c->policy.route) {
llog(RC_LOG, c->logger, "connection is already routed");
return 0; /* not counted */
}
if (c->routing.state == RT_UNROUTED) {
/* both install policy and route connection */
connection_route(c, HERE);
return 1; /* counted */
}
if (kernel_route_installed(c)) {
/*
* Need to stop the connection unrouting.
*
* For instance, a connection in state ROUTED_TUNNEL
* and with -ROUTE will still have the kernel route
* and policy installed. Add +ROUTE so that when the
* connection fails or is taken down, ondemand routing
* remains in place.
*
* Note that is includes states such as
* ROUTED_ONDEMAND which happens when a connection as
* +UP -ROUTE.
*/
add_policy(c, policy.route);
llog(RC_LOG, c->logger, "connection will remain routed");
return 1;
}
/*
* These are assumed to be in-flight connections.
*/
llog(RC_LOG, c->logger, "connection marked for routing");
return 1;
}
static unsigned whack_route_connection(const struct whack_message *m UNUSED,
struct show *s,
struct connection *c)
{
connection_attach(c, show_logger(s));
unsigned rc = maybe_route_connection(c);
connection_detach(c, show_logger(s));
return rc;
}
void whack_route(const struct whack_message *m, struct show *s)
{
if (!listening) {
whack_log(RC_DEAF, s,
"need --listen before --route");
return;
}
if (m->name == NULL) {
/* leave bread crumb */
whack_log(RC_FATAL, s,
"received command to route connection, but did not receive the connection name - ignored");
return;
}
whack_connections_bottom_up(m, s, whack_route_connection,
(struct each) {
.log_unknown_name = true,
});
}
|