]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
connmark: Consider configured mask in installed firewall rules
authorTobias Brunner <tobias@strongswan.org>
Fri, 17 Jun 2022 10:10:19 +0000 (12:10 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 18 Jul 2022 13:05:51 +0000 (15:05 +0200)
This allows using the upper parts of the marks for other purposes.  For
instance, with `mark_in=mark_out=%unique/0x0000ffff` mark values in the
upper two bytes would not get reset by the rules installed by this plugin.
However, note that in this example the daemon would have to get restarted
after 65'535 CHILD_SAs to reset the counter for unique marks, which is a
global 32-bit counter that's unaware of any masks.

Closes strongswan/strongswan#1087

src/libcharon/plugins/connmark/connmark_listener.c

index 58290b938c9e0c4dc07bf295a8e085ed4bbebc98..702fc33e5b995f1b169ebaa5f9ffc9a4a9fbcf01 100644 (file)
@@ -119,7 +119,7 @@ static bool manage_rule(struct iptc_handle *ipth, const char *chain,
  */
 static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
                                                                  struct iptc_handle *ipth, bool add,
-                                                                 u_int mark, uint32_t spi,
+                                                                 uint32_t mark, uint32_t mask, uint32_t spi,
                                                                  host_t *dst, host_t *src)
 {
        uint16_t match_size     = XT_ALIGN(sizeof(struct ipt_entry_match)) +
@@ -167,7 +167,7 @@ static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
        );
        ADD_STRUCT(pos, struct xt_mark_tginfo2,
                .mark = mark,
-               .mask = ~0,
+               .mask = mask,
        );
        return manage_rule(ipth, "PREROUTING", add, e);
 }
@@ -177,7 +177,7 @@ static bool manage_pre_esp_in_udp(private_connmark_listener_t *this,
  */
 static bool manage_pre_esp(private_connmark_listener_t *this,
                                                   struct iptc_handle *ipth, bool add,
-                                                  u_int mark, uint32_t spi,
+                                                  uint32_t mark, uint32_t mask, uint32_t spi,
                                                   host_t *dst, host_t *src)
 {
        uint16_t match_size     = XT_ALIGN(sizeof(struct ipt_entry_match)) +
@@ -224,7 +224,7 @@ static bool manage_pre_esp(private_connmark_listener_t *this,
        );
        ADD_STRUCT(pos, struct xt_mark_tginfo2,
                .mark = mark,
-               .mask = ~0,
+               .mask = mask,
        );
        return manage_rule(ipth, "PREROUTING", add, e);
 }
@@ -234,14 +234,14 @@ static bool manage_pre_esp(private_connmark_listener_t *this,
  */
 static bool manage_pre(private_connmark_listener_t *this,
                                           struct iptc_handle *ipth, bool add,
-                                          u_int mark, uint32_t spi, bool encap,
+                                          uint32_t mark, uint32_t mask, uint32_t spi, bool encap,
                                           host_t *dst, host_t *src)
 {
        if (encap)
        {
-               return manage_pre_esp_in_udp(this, ipth, add, mark, spi, dst, src);
+               return manage_pre_esp_in_udp(this, ipth, add, mark, mask, spi, dst, src);
        }
-       return manage_pre_esp(this, ipth, add, mark, spi, dst, src);
+       return manage_pre_esp(this, ipth, add, mark, mask, spi, dst, src);
 }
 
 /**
@@ -249,7 +249,7 @@ static bool manage_pre(private_connmark_listener_t *this,
  */
 static bool manage_in(private_connmark_listener_t *this,
                                          struct iptc_handle *ipth, bool add,
-                                         u_int mark, uint32_t spi,
+                                         uint32_t mark, uint32_t mask, uint32_t spi,
                                          traffic_selector_t *dst, traffic_selector_t *src)
 {
        uint16_t match_size     = XT_ALIGN(sizeof(struct ipt_entry_match)) +
@@ -300,8 +300,8 @@ static bool manage_in(private_connmark_listener_t *this,
        );
        ADD_STRUCT(pos, struct xt_connmark_tginfo1,
                .ctmark = mark,
-               .ctmask = ~0,
-               .nfmask = ~0,
+               .ctmask = mask,
+               .nfmask = mask,
                .mode = XT_CONNMARK_SET,
        );
        return manage_rule(ipth, "INPUT", add, e);
@@ -312,7 +312,7 @@ static bool manage_in(private_connmark_listener_t *this,
  * already has a mark set
  */
 static bool manage_out(private_connmark_listener_t *this,
-                                          struct iptc_handle *ipth, bool add,
+                                          struct iptc_handle *ipth, bool add, uint32_t mask,
                                           traffic_selector_t *dst, traffic_selector_t *src)
 {
        uint16_t match_size     = XT_ALIGN(sizeof(struct ipt_entry_match)) +
@@ -344,7 +344,7 @@ static bool manage_out(private_connmark_listener_t *this,
                },
        );
        ADD_STRUCT(pos, struct xt_mark_mtinfo1,
-               .mask = ~0,
+               .mask = mask,
        );
        ADD_STRUCT(pos, struct ipt_entry_target,
                .u = {
@@ -356,8 +356,8 @@ static bool manage_out(private_connmark_listener_t *this,
                },
        );
        ADD_STRUCT(pos, struct xt_connmark_tginfo1,
-               .ctmask = ~0,
-               .nfmask = ~0,
+               .ctmask = mask,
+               .nfmask = mask,
                .mode = XT_CONNMARK_RESTORE,
        );
        return manage_rule(ipth, "OUTPUT", add, e);
@@ -401,19 +401,19 @@ static bool manage_policies(private_connmark_listener_t *this,
 {
        traffic_selector_t *local, *remote;
        enumerator_t *enumerator;
-       uint32_t spi;
-       u_int mark;
+       uint32_t spi, mark, mask;
        bool done = TRUE;
 
        spi = child_sa->get_spi(child_sa, TRUE);
        mark = child_sa->get_mark(child_sa, TRUE).value;
+       mask = child_sa->get_mark(child_sa, TRUE).mask;
 
        enumerator = child_sa->create_policy_enumerator(child_sa);
        while (enumerator->enumerate(enumerator, &local, &remote))
        {
-               if (!manage_pre(this, ipth, add, mark, spi, encap, dst, src) ||
-                       !manage_in(this, ipth, add, mark, spi, local, remote) ||
-                       !manage_out(this, ipth, add, remote, local))
+               if (!manage_pre(this, ipth, add, mark, mask, spi, encap, dst, src) ||
+                       !manage_in(this, ipth, add, mark, mask, spi, local, remote) ||
+                       !manage_out(this, ipth, add, mask, remote, local))
                {
                        done = FALSE;
                        break;