Hi,

thanks, i like this.

but your diff does not seem to be against -current, you started from 6.0

But even with 6.0 i get rejects, maybe you mail client messes this up.

Can you please resend a good diff?

/Benno



Bertrand Provost(provost.bertr...@gmail.com) on 2017.01.24 16:53:02 -0500:
> Hi,
> 
> This patch fix `pfctl` to be able to kill states within a rdomain.
> Currently only states in rdomain 0 can be kill when using host or label
> because check is done in ioctl DIOCKILLSTATES
> 
> sys/net/pf_ioctl.c:
>    `psk->psk_rdomain == sk->rdomain`
> 
> I used -V like `arp`, `ping`... but it could be done too with
> `route -T id exec` and `getrtable()` (don't know which one is the
> best here since it related to rdomain and not rtable).
> 
> Also `const char *iface` arg was not used in `pfctl_id_kill_states`.
> 
> To reproduce the bug:
> 
>    # ifconfig pair1 rdomain 1 10.1.1.1/24 up
>    # ifconfig pair2 rdomain 2 10.1.1.2/24 up
>    # ifconfig pair1 patch pair2
>    # route -T 1 exec ping 10.1.1.2
> 
> Then start a server
> 
>    # route -T2 exec nc -vl 10.1.1.2 4242
> 
> And connect to it
> 
>    # route -T1 exec nc 10.1.1.2 4242
> 
> Display states:
> 
>    # pfctl -v -ss
>    all tcp (2) 10.1.1.2:4242 <- (2) 10.1.1.1:13194 ESTABLISHED:ESTABLISHED
>       [4248582619 + 16384] wscale 3  [1432845864 + 17376] wscale 3
>       age 00:00:58, expires in 23:59:05, 3:2 pkts, 174:116 bytes, rule 1
> 
> Kill it
> 
>    # pfctl -k 10.1.1.2
>    killed 0 states from 1 sources and 0 destinations
> 
> or
> 
>    # pfctl -k 10.1.1.1
>    killed 0 states from 1 sources and 0 destinations
> 
> But state is still here and connection is still established.
> 
>    # pfctl -v -ss
>    all tcp (2) 10.1.1.2:4242 <- (2) 10.1.1.1:13194 ESTABLISHED:ESTABLISHED
>       [4248582625 + 16384] wscale 3  [1432845864 + 17376] wscale 3
>       age 00:04:49, expires in 23:56:29, 4:3 pkts, 226:174 bytes, rule 1
> 
> Regards,
> 
> -- 
> Bertrand Provost
> 
> Index: pfctl.8
> ===================================================================
> RCS file: /cvs/src/sbin/pfctl/pfctl.8,v
> retrieving revision 1.165
> diff -u -p -r1.165 pfctl.8
> --- pfctl.8   15 Jun 2015 08:48:23 -0000      1.165
> +++ pfctl.8   24 Jan 2017 21:38:56 -0000
> @@ -47,6 +47,7 @@
>   .Op Fl S Ar statefile
>   .Op Fl s Ar modifier Op Fl R Ar id
>   .Op Fl t Ar table Fl T Ar command Op Ar address ...
> +.Op Fl V Ar rdomain
>   .Op Fl x Ar level
>   .Ek
>   .Sh DESCRIPTION
> @@ -275,6 +276,12 @@ from rules carrying the label
>   .Dq foobar :
>   .Pp
>   .Dl # pfctl -k label -k foobar
> +.Pp
> +To kill states withing a rdomain (the rdomain of a state is displayed
> +in parentheses before the host by pfctl -s states) use
> +.Fl V Ar rdomain :
> +.Pp
> +.Dl # pfctl -V rdomain -k host
>   .Pp
>   To kill one specific state by its unique state ID
>   (as shown by pfctl -s state -vv),
> Index: pfctl.c
> ===================================================================
> RCS file: /cvs/src/sbin/pfctl/pfctl.c,v
> retrieving revision 1.334
> diff -u -p -r1.334 pfctl.c
> --- pfctl.c   14 Jan 2016 12:05:51 -0000      1.334
> +++ pfctl.c   24 Jan 2017 21:38:56 -0000
> @@ -69,9 +69,9 @@ int  pfctl_clear_src_nodes(int, int);
>   int  pfctl_clear_states(int, const char *, int);
>   void         pfctl_addrprefix(char *, struct pf_addr *);
>   int  pfctl_kill_src_nodes(int, const char *, int);
> -int   pfctl_net_kill_states(int, const char *, int);
> -int   pfctl_label_kill_states(int, const char *, int);
> -int   pfctl_id_kill_states(int, const char *, int);
> +int   pfctl_net_kill_states(int, const char *, int, int);
> +int   pfctl_label_kill_states(int, const char *, int, int);
> +int   pfctl_id_kill_states(int, int);
>   void         pfctl_init_options(struct pfctl *);
>   int  pfctl_load_options(struct pfctl *);
>   int  pfctl_load_limit(struct pfctl *, unsigned int, unsigned int);
> @@ -512,7 +512,7 @@ pfctl_kill_src_nodes(int dev, const char
>   }
> 
>   int
> -pfctl_net_kill_states(int dev, const char *iface, int opts)
> +pfctl_net_kill_states(int dev, const char *iface, int opts, int rdomain)
>   {
>       struct pfioc_state_kill psk;
>       struct addrinfo *res[2], *resp[2];
> @@ -531,6 +531,8 @@ pfctl_net_kill_states(int dev, const cha
>           sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
>               errx(1, "invalid interface: %s", iface);
> 
> +     psk.psk_rdomain = rdomain;
> +
>       pfctl_addrprefix(state_kill[0], &psk.psk_src.addr.v.a.mask);
> 
>       if ((ret_ga = getaddrinfo(state_kill[0], NULL, NULL, &res[0]))) {
> @@ -618,7 +620,7 @@ pfctl_net_kill_states(int dev, const cha
>   }
> 
>   int
> -pfctl_label_kill_states(int dev, const char *iface, int opts)
> +pfctl_label_kill_states(int dev, const char *iface, int opts, int rdomain)
>   {
>       struct pfioc_state_kill psk;
> 
> @@ -635,6 +637,8 @@ pfctl_label_kill_states(int dev, const c
>           sizeof(psk.psk_label))
>               errx(1, "label too long: %s", state_kill[1]);
> 
> +     psk.psk_rdomain = rdomain;
> +
>       if (ioctl(dev, DIOCKILLSTATES, &psk))
>               err(1, "DIOCKILLSTATES");
> 
> @@ -645,7 +649,7 @@ pfctl_label_kill_states(int dev, const c
>   }
> 
>   int
> -pfctl_id_kill_states(int dev, const char *iface, int opts)
> +pfctl_id_kill_states(int dev, int opts)
>   {
>       struct pfioc_state_kill psk;
> 
> @@ -2098,6 +2102,7 @@ main(int argc, char *argv[])
>       int      opts = 0;
>       int      optimize = PF_OPTIMIZE_BASIC;
>       int      level;
> +     int      rdomain = 0;
>       char     anchorname[PATH_MAX];
>       int      anchor_wildcard = 0;
>       char    *path;
> @@ -2109,7 +2114,7 @@ main(int argc, char *argv[])
>               usage();
> 
>       while ((ch = getopt(argc, argv,
> -         "a:dD:eqf:F:ghi:k:K:L:no:Pp:R:rS:s:t:T:vx:z")) != -1) {
> +         "a:dD:eqf:F:ghi:k:K:L:no:Pp:R:rS:s:t:T:vV:x:z")) != -1) {
>               switch (ch) {
>               case 'a':
>                       anchoropt = optarg;
> @@ -2215,6 +2220,13 @@ main(int argc, char *argv[])
>                               opts |= PF_OPT_VERBOSE2;
>                       opts |= PF_OPT_VERBOSE;
>                       break;
> +             case 'V':
> +                     rdomain = strtonum(optarg, 0, RT_TABLEID_MAX, 
> &errstr);
> +                     if (errstr) {
> +                             warnx("Invalid rdomain: %s", errstr);
> +                             usage();
> +                     }
> +                     break;
>               case 'x':
>                       debugopt = pfctl_lookup_option(optarg, 
>                       debugopt_list);
>                       if (debugopt == NULL) {
> @@ -2403,11 +2415,11 @@ main(int argc, char *argv[])
>       }
>       if (state_killers) {
>               if (!strcmp(state_kill[0], "label"))
> -                     pfctl_label_kill_states(dev, ifaceopt, opts);
> +                     pfctl_label_kill_states(dev, ifaceopt, opts, 
> rdomain);
>               else if (!strcmp(state_kill[0], "id"))
> -                     pfctl_id_kill_states(dev, ifaceopt, opts);
> +                     pfctl_id_kill_states(dev, opts);
>               else
> -                     pfctl_net_kill_states(dev, ifaceopt, opts);
> +                     pfctl_net_kill_states(dev, ifaceopt, opts, rdomain);
>       }
> 
>       if (src_node_killers)
> 

Reply via email to