[patch] Reloading pf rules breaks connections on lo0

Andreas Longwitz longwitz at incore.de
Tue Apr 2 08:41:35 UTC 2013


Ermal Luçi wrote:

> Looks ok.
> Can you make the changes so i can push it?
Yes, now the patch looks like this:

--- pfctl.c.orig        2013-01-14 15:17:48.000000000 +0100
+++ pfctl.c     2013-04-02 10:24:21.000000000 +0200
@@ -67,6 +67,9 @@
 int     pfctl_enable(int, int);
 int     pfctl_disable(int, int);
 int     pfctl_clear_stats(int, int);
+int     pfctl_get_skip_ifaces(void);
+int     pfctl_check_skip_ifaces(char *);
+int     pfctl_clear_skip_ifaces(struct pfctl *);
 int     pfctl_clear_interface_flags(int, int);
 int     pfctl_clear_rules(int, int, char *);
 int     pfctl_clear_nat(int, int, char *);
@@ -105,6 +108,8 @@
 struct pf_anchor_global         pf_anchors;
 struct pf_anchor        pf_main_anchor;

+static struct pfr_buffer skip_b;
+
 const char     *clearopt;
 char           *rulesopt;
 const char     *showopt;
@@ -297,6 +302,44 @@
 }

 int
+pfctl_get_skip_ifaces(void)
+{
+       bzero(&skip_b, sizeof(skip_b));
+       skip_b.pfrb_type = PFRB_IFACES;
+       for (;;) {
+               pfr_buf_grow(&skip_b, skip_b.pfrb_size);
+               skip_b.pfrb_size = skip_b.pfrb_msize;
+               if (pfi_get_ifaces(NULL, skip_b.pfrb_caddr,
&skip_b.pfrb_size))
+                       err(1, "pfi_get_ifaces");
+               if (skip_b.pfrb_size <= skip_b.pfrb_msize)
+                       break;
+       }
+       return (0);
+}
+
+int
+pfctl_check_skip_ifaces(char *ifname)
+{
+       struct pfi_kif          *p;
+
+       PFRB_FOREACH(p, &skip_b)
+               if ((p->pfik_flags & PFI_IFLAG_SKIP) && !strcmp(ifname,
p->pfik_name))
+                       p->pfik_flags &= ~PFI_IFLAG_SKIP;
+       return (0);
+}
+
+int
+pfctl_clear_skip_ifaces(struct pfctl *pf)
+{
+       struct pfi_kif          *p;
+
+       PFRB_FOREACH(p, &skip_b)
+               if (p->pfik_flags & PFI_IFLAG_SKIP)
+                       pfctl_set_interface_flags(pf, p->pfik_name,
PFI_IFLAG_SKIP, 0);
+       return (0);
+}
+
+int
 pfctl_clear_interface_flags(int dev, int opts)
 {
        struct pfioc_iface      pi;
@@ -1437,6 +1480,8 @@
                else
                        goto _error;
        }
+       if (loadopt & PFCTL_FLAG_OPTION)
+               pfctl_clear_skip_ifaces(&pf);

        if ((pf.loadopt & PFCTL_FLAG_FILTER &&
            (pfctl_load_ruleset(&pf, path, rs, PF_RULESET_SCRUB, 0))) ||
@@ -1861,6 +1906,7 @@
                } else {
                        if (ioctl(pf->dev, DIOCSETIFFLAG, &pi))
                                err(1, "DIOCSETIFFLAG");
+                       pfctl_check_skip_ifaces(ifname);
                }
        }
        return (0);
@@ -2340,7 +2386,7 @@
        }
        if ((rulesopt != NULL) && (loadopt & PFCTL_FLAG_OPTION) &&
            !anchorname[0])
-               if (pfctl_clear_interface_flags(dev, opts | PF_OPT_QUIET))
+               if (pfctl_get_skip_ifaces())
                        error = 1;

        if (rulesopt != NULL && !(opts & (PF_OPT_MERGE|PF_OPT_NOACTION)) &&


-- 
Andreas Longwitz



More information about the freebsd-pf mailing list