Author: kp
Date: Sat Apr 28 13:16:58 2018
New Revision: 333084
URL: https://svnweb.freebsd.org/changeset/base/333084

Log:
  pfctl: Don't break connections on skipped interfaces on reload
  
  On reload we used to first flush everything, including the list of skipped
  interfaces.  This can lead to termination of these connections if they send
  packets before the new configuration is applied.
  
  Note that this doesn't currently happen on 12 or 11, because of special EACCES
  handling introduced in r315514. This special behaviour in tcp_output() may
  change, hence the fix in pfctl.
  
  PR:           214613

Modified:
  head/sbin/pfctl/pfctl.c

Modified: head/sbin/pfctl/pfctl.c
==============================================================================
--- head/sbin/pfctl/pfctl.c     Sat Apr 28 12:24:05 2018        (r333083)
+++ head/sbin/pfctl/pfctl.c     Sat Apr 28 13:16:58 2018        (r333084)
@@ -67,6 +67,9 @@ void   usage(void);
 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 *);
@@ -106,6 +109,7 @@ const char  *pfctl_lookup_option(char *, const char * c
 
 static struct pf_anchor_global  pf_anchors;
 static struct pf_anchor         pf_main_anchor;
+static struct pfr_buffer skip_b;
 
 static const char      *clearopt;
 static char            *rulesopt;
@@ -295,6 +299,44 @@ pfctl_clear_stats(int dev, int opts)
 }
 
 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;
@@ -1479,6 +1521,8 @@ pfctl_rules(int dev, char *filename, int opts, int opt
                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))) ||
@@ -1889,6 +1933,7 @@ pfctl_set_interface_flags(struct pfctl *pf, char *ifna
                } else {
                        if (ioctl(pf->dev, DIOCSETIFFLAG, &pi))
                                err(1, "DIOCSETIFFLAG");
+                       pfctl_check_skip_ifaces(ifname);
                }
        }
        return (0);
@@ -2347,7 +2392,7 @@ main(int argc, char *argv[])
 
        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)) &&
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to