Hello,

this is the second patch in 3-patch series.

Patch changes DIOCRDELADDRS ioctl to DIOCRDELADDR, which accepts one IP address
only per ioctl(2) call. Patch updates kernel and pfctl(8) only. Other 
components,
which happen to use DIOCRDELADDRS will be updated by extra patch.

thanks and
regards
sasha

--------8<---------------8<---------------8<------------------8<--------

Index: sbin/pfctl/pfctl_radix.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_radix.c,v
retrieving revision 1.32
diff -u -p -r1.32 pfctl_radix.c
--- sbin/pfctl/pfctl_radix.c    21 Jan 2015 21:50:33 -0000      1.32
+++ sbin/pfctl/pfctl_radix.c    27 Oct 2015 22:56:54 -0000
@@ -207,6 +207,7 @@ pfr_del_addrs(struct pfr_table *tbl, str
     int *ndel, int flags)
 {
        struct pfioc_table io;
+       int     i, rv, del = 0;
 
        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
                errno = EINVAL;
@@ -215,14 +216,18 @@ pfr_del_addrs(struct pfr_table *tbl, str
        bzero(&io, sizeof io);
        io.pfrio_flags = flags;
        io.pfrio_table = *tbl;
-       io.pfrio_buffer = addr;
        io.pfrio_esize = sizeof(*addr);
-       io.pfrio_size = size;
-       if (ioctl(dev, DIOCRDELADDRS, &io))
-               return (-1);
-       if (ndel != NULL)
-               *ndel = io.pfrio_ndel;
-       return (0);
+       io.pfrio_size = 1;
+       for (i = 0; (i < size) && (rv == 0); i++) {
+               io.pfrio_buffer = addr++;
+               rv = ioctl(dev, DIOCRDELADDR, &io);
+               del++;
+       }
+
+       if ((rv == 0) && (ndel != NULL))
+               *ndel = del;
+
+       return (rv);
 }
 
 int
Index: sys/net/pf_ioctl.c
===================================================================
RCS file: /cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.291
diff -u -p -r1.291 pf_ioctl.c
--- sys/net/pf_ioctl.c  13 Oct 2015 19:32:31 -0000      1.291
+++ sys/net/pf_ioctl.c  27 Oct 2015 22:57:20 -0000
@@ -835,7 +835,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                case DIOCRCLRTSTATS:
                case DIOCRCLRADDRS:
                case DIOCRADDADDRS:
-               case DIOCRDELADDRS:
+               case DIOCRDELADDR:
                case DIOCRSETADDRS:
                case DIOCRGETASTATS:
                case DIOCRCLRASTATS:
@@ -888,7 +888,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                case DIOCRCLRTSTATS:
                case DIOCRCLRADDRS:
                case DIOCRADDADDRS:
-               case DIOCRDELADDRS:
+               case DIOCRDELADDR:
                case DIOCRSETADDRS:
                case DIOCRSETTFLAGS:
                        if (((struct pfioc_table *)addr)->pfrio_flags &
@@ -1829,16 +1829,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a
                break;
        }
 
-       case DIOCRDELADDRS: {
+       case DIOCRDELADDR: {
                struct pfioc_table *io = (struct pfioc_table *)addr;
 
                if (io->pfrio_esize != sizeof(struct pfr_addr)) {
                        error = ENODEV;
                        break;
                }
-               error = pfr_del_addrs(&io->pfrio_table, io->pfrio_buffer,
-                   io->pfrio_size, &io->pfrio_ndel, io->pfrio_flags |
-                   PFR_FLAG_USERIOCTL);
+               error = pfr_del_addr(&io->pfrio_table, io->pfrio_buffer,
+                   io->pfrio_size, io->pfrio_flags | PFR_FLAG_USERIOCTL);
                break;
        }
 
Index: sys/net/pf_table.c
===================================================================
RCS file: /cvs/src/sys/net/pf_table.c,v
retrieving revision 1.115
diff -u -p -r1.115 pf_table.c
--- sys/net/pf_table.c  7 Oct 2015 11:57:44 -0000       1.115
+++ sys/net/pf_table.c  27 Oct 2015 22:57:24 -0000
@@ -152,6 +152,8 @@ void                         pfr_destroy_kentries(struct 
pfr_
 void                    pfr_destroy_kentry(struct pfr_kentry *);
 void                    pfr_insert_kentries(struct pfr_ktable *,
                            struct pfr_kentryworkq *, time_t);
+void                    pfr_remove_kentry(struct pfr_ktable *,
+                           struct pfr_kentry *);
 void                    pfr_remove_kentries(struct pfr_ktable *,
                            struct pfr_kentryworkq *);
 void                    pfr_clstats_kentries(struct pfr_kentryworkq *, time_t,
@@ -343,14 +345,12 @@ _bad:
 }
 
 int
-pfr_del_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
-    int *ndel, int flags)
+pfr_del_addr(struct pfr_table *tbl, struct pfr_addr *addr, int size, int flags)
 {
        struct pfr_ktable       *kt;
-       struct pfr_kentryworkq   workq;
        struct pfr_kentry       *p;
        struct pfr_addr          ad;
-       int                      i, rv, xdel = 0, log = 1;
+       int                      rv;
 
        ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY | PFR_FLAG_FEEDBACK);
        if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL))
@@ -360,70 +360,29 @@ pfr_del_addrs(struct pfr_table *tbl, str
                return (ESRCH);
        if (kt->pfrkt_flags & PFR_TFLAG_CONST)
                return (EPERM);
-       /*
-        * there are two algorithms to choose from here.
-        * with:
-        *   n: number of addresses to delete
-        *   N: number of addresses in the table
-        *
-        * one is O(N) and is better for large 'n'
-        * one is O(n*LOG(N)) and is better for small 'n'
-        * 
-        * following code try to decide which one is best.
-        */
-       for (i = kt->pfrkt_cnt; i > 0; i >>= 1)
-               log++;
-       if (size > kt->pfrkt_cnt/log) {
-               /* full table scan */
-               pfr_mark_addrs(kt);
-       } else {
-               /* iterate over addresses to delete */
-               for (i = 0; i < size; i++) {
-                       YIELD(i, flags & PFR_FLAG_USERIOCTL);
-                       if (COPYIN(addr+i, &ad, sizeof(ad), flags))
-                               return (EFAULT);
-                       if (pfr_validate_addr(&ad))
-                               return (EINVAL);
-                       p = pfr_lookup_addr(kt, &ad, 1);
-                       if (p != NULL)
-                               p->pfrke_flags &= ~PFRKE_FLAG_MARK;
-               }
-       }
-       SLIST_INIT(&workq);
-       for (i = 0; i < size; i++) {
-               YIELD(i, flags & PFR_FLAG_USERIOCTL);
-               if (COPYIN(addr+i, &ad, sizeof(ad), flags))
+
+       if (COPYIN(addr, &ad, sizeof(ad), flags))
+               senderr(EFAULT);
+       if (pfr_validate_addr(&ad))
+               senderr(EINVAL);
+       p = pfr_lookup_addr(kt, &ad, 1);
+       if (flags & PFR_FLAG_FEEDBACK) {
+               if (p == NULL)
+                       ad.pfra_fback = PFR_FB_NONE;
+               else if ((p->pfrke_flags & PFRKE_FLAG_NOT) !=
+                   ad.pfra_not)
+                       ad.pfra_fback = PFR_FB_CONFLICT;
+               else
+                       ad.pfra_fback = PFR_FB_DELETED;
+
+               if (COPYOUT(&ad, addr, sizeof(ad), flags))
                        senderr(EFAULT);
-               if (pfr_validate_addr(&ad))
-                       senderr(EINVAL);
-               p = pfr_lookup_addr(kt, &ad, 1);
-               if (flags & PFR_FLAG_FEEDBACK) {
-                       if (p == NULL)
-                               ad.pfra_fback = PFR_FB_NONE;
-                       else if ((p->pfrke_flags & PFRKE_FLAG_NOT) !=
-                           ad.pfra_not)
-                               ad.pfra_fback = PFR_FB_CONFLICT;
-                       else if (p->pfrke_flags & PFRKE_FLAG_MARK)
-                               ad.pfra_fback = PFR_FB_DUPLICATE;
-                       else
-                               ad.pfra_fback = PFR_FB_DELETED;
-               }
-               if (p != NULL &&
-                   (p->pfrke_flags & PFRKE_FLAG_NOT) == ad.pfra_not &&
-                   !(p->pfrke_flags & PFRKE_FLAG_MARK)) {
-                       p->pfrke_flags |= PFRKE_FLAG_MARK;
-                       SLIST_INSERT_HEAD(&workq, p, pfrke_workq);
-                       xdel++;
-               }
-               if (flags & PFR_FLAG_FEEDBACK)
-                       if (COPYOUT(&ad, addr+i, sizeof(ad), flags))
-                               senderr(EFAULT);
        }
-       if (!(flags & PFR_FLAG_DUMMY)) {
-               pfr_remove_kentries(kt, &workq);
+
+       if (!(flags & PFR_FLAG_DUMMY) && (p != NULL)) {
+               pfr_remove_kentry(kt, p);
        }
-       if (ndel != NULL)
-               *ndel = xdel;
+
        return (0);
 _bad:
        if (flags & PFR_FLAG_FEEDBACK)
@@ -947,6 +906,25 @@ pfr_insert_kentry(struct pfr_ktable *kt,
        pfr_ktable_winfo_update(kt, p);
 
        return (0);
+}
+
+void
+pfr_remove_kentry(struct pfr_ktable *kt, struct pfr_kentry *p)
+{
+       struct pfr_kentryworkq   addrq;
+
+       pfr_unroute_kentry(kt, p);
+       if (p->pfrke_type == PFRKE_COST)
+               kt->pfrkt_refcntcost--;
+       kt->pfrkt_cnt--;
+
+       if (kt->pfrkt_refcntcost > 0) {
+               kt->pfrkt_gcdweight = 0;
+               kt->pfrkt_maxweight = 1;
+               pfr_enqueue_addrs(kt, &addrq, NULL, 0);
+               SLIST_FOREACH(p, &addrq, pfrke_workq)
+                       pfr_ktable_winfo_update(kt, p);
+       }
 }
 
 void
Index: sys/net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.421
diff -u -p -r1.421 pfvar.h
--- sys/net/pfvar.h     13 Oct 2015 19:32:32 -0000      1.421
+++ sys/net/pfvar.h     27 Oct 2015 22:57:25 -0000
@@ -1614,7 +1614,7 @@ struct pfioc_iface {
 #define DIOCRCLRTSTATS  _IOWR('D', 65, struct pfioc_table)
 #define        DIOCRCLRADDRS   _IOWR('D', 66, struct pfioc_table)
 #define        DIOCRADDADDRS   _IOWR('D', 67, struct pfioc_table)
-#define        DIOCRDELADDRS   _IOWR('D', 68, struct pfioc_table)
+#define        DIOCRDELADDR    _IOWR('D', 68, struct pfioc_table)
 #define        DIOCRSETADDRS   _IOWR('D', 69, struct pfioc_table)
 #define        DIOCRGETADDRS   _IOWR('D', 70, struct pfioc_table)
 #define        DIOCRGETASTATS  _IOWR('D', 71, struct pfioc_table)
@@ -1791,8 +1791,7 @@ int       pfr_clr_addrs(struct pfr_table *, in
 int    pfr_insert_kentry(struct pfr_ktable *, struct pfr_addr *, time_t);
 int    pfr_add_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
            int);
-int    pfr_del_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
-           int);
+int    pfr_del_addr(struct pfr_table *, struct pfr_addr *, int, int);
 int    pfr_set_addrs(struct pfr_table *, struct pfr_addr *, int, int *,
            int *, int *, int *, int, u_int32_t);
 int    pfr_get_addrs(struct pfr_table *, struct pfr_addr *, int *, int);
Index: sbin/pfctl/pfctl_radix.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_radix.c,v
retrieving revision 1.32
diff -u -p -r1.32 pfctl_radix.c
--- sbin/pfctl/pfctl_radix.c    21 Jan 2015 21:50:33 -0000      1.32
+++ sbin/pfctl/pfctl_radix.c    27 Oct 2015 22:59:35 -0000
@@ -207,6 +207,7 @@ pfr_del_addrs(struct pfr_table *tbl, str
     int *ndel, int flags)
 {
        struct pfioc_table io;
+       int     i, rv, del = 0;
 
        if (tbl == NULL || size < 0 || (size && addr == NULL)) {
                errno = EINVAL;
@@ -215,14 +216,18 @@ pfr_del_addrs(struct pfr_table *tbl, str
        bzero(&io, sizeof io);
        io.pfrio_flags = flags;
        io.pfrio_table = *tbl;
-       io.pfrio_buffer = addr;
        io.pfrio_esize = sizeof(*addr);
-       io.pfrio_size = size;
-       if (ioctl(dev, DIOCRDELADDRS, &io))
-               return (-1);
-       if (ndel != NULL)
-               *ndel = io.pfrio_ndel;
-       return (0);
+       io.pfrio_size = 1;
+       for (i = 0; (i < size) && (rv == 0); i++) {
+               io.pfrio_buffer = addr++;
+               rv = ioctl(dev, DIOCRDELADDR, &io);
+               del++;
+       }
+
+       if ((rv == 0) && (ndel != NULL))
+               *ndel = del;
+
+       return (rv);
 }
 
 int

Reply via email to