summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/bypass_lan
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2019-01-02 10:45:36 +0100
committerYves-Alexis Perez <corsac@debian.org>2019-01-02 11:07:05 +0100
commit918094fde55fa0dbfd59a5f88d576efb513a88db (patch)
tree61e31656c60a6cc928c50cd633568043673e2cbd /src/libcharon/plugins/bypass_lan
parent69bc96f6b0b388d35e983f8d27224fa49d92918c (diff)
downloadvyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.tar.gz
vyos-strongswan-918094fde55fa0dbfd59a5f88d576efb513a88db.zip
New upstream version 5.7.2
Diffstat (limited to 'src/libcharon/plugins/bypass_lan')
-rw-r--r--src/libcharon/plugins/bypass_lan/bypass_lan_listener.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
index 644cff029..1abbf7731 100644
--- a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
+++ b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c
@@ -64,6 +64,7 @@ typedef struct {
private_bypass_lan_listener_t *listener;
host_t *net;
uint8_t mask;
+ char *iface;
child_cfg_t *cfg;
} bypass_policy_t;
@@ -85,6 +86,7 @@ static void bypass_policy_destroy(bypass_policy_t *this)
ts->destroy(ts);
}
this->net->destroy(this->net);
+ free(this->iface);
free(this);
}
@@ -126,6 +128,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
enumerator_t *enumerator;
hashtable_t *seen;
bypass_policy_t *found, *lookup;
+ traffic_selector_t *ts;
host_t *net;
uint8_t mask;
char *iface;
@@ -146,6 +149,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
INIT(lookup,
.net = net->clone(net),
.mask = mask,
+ .iface = strdupnull(iface),
);
found = seen->put(seen, lookup, lookup);
if (found)
@@ -160,7 +164,6 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
.mode = MODE_PASS,
};
child_cfg_t *cfg;
- traffic_selector_t *ts;
char name[128];
ts = traffic_selector_create_from_subnet(net->clone(net), mask,
@@ -176,6 +179,7 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
INIT(found,
.net = net->clone(net),
.mask = mask,
+ .iface = strdupnull(iface),
.cfg = cfg,
);
this->policies->put(this->policies, found, found);
@@ -186,11 +190,29 @@ static job_requeue_t update_bypass(private_bypass_lan_listener_t *this)
enumerator = this->policies->create_enumerator(this->policies);
while (enumerator->enumerate(enumerator, NULL, &lookup))
{
- if (!seen->get(seen, lookup))
+ found = seen->get(seen, lookup);
+ if (!found)
{
this->policies->remove_at(this->policies, enumerator);
bypass_policy_destroy(lookup);
}
+ else if (!streq(lookup->iface, found->iface))
+ { /* if the subnet is on multiple interfaces, we only get the last
+ * one (hopefully, they are enumerated in a consistent order) */
+ ts = traffic_selector_create_from_subnet(
+ lookup->net->clone(lookup->net),
+ lookup->mask, 0, 0, 65535);
+ DBG1(DBG_IKE, "interface change for bypass policy for %R (from %s "
+ "to %s)", ts, lookup->iface, found->iface);
+ ts->destroy(ts);
+ free(lookup->iface);
+ lookup->iface = strdupnull(found->iface);
+ /* there is currently no API to update shunts, so we remove and
+ * reinstall it to update the route */
+ charon->shunts->uninstall(charon->shunts, "bypass-lan",
+ lookup->cfg->get_name(lookup->cfg));
+ charon->shunts->install(charon->shunts, "bypass-lan", lookup->cfg);
+ }
}
enumerator->destroy(enumerator);
this->mutex->unlock(this->mutex);