Hi,
This converts the pf rule structure to use the divert type.
Old semantics was:
divert.port: divert-to or divert-reply
divert.addr: divert-to
divert_packet.port: divert-packet
Now we have one divert structure with an explicit type.
ok?
bluhm
Index: sys/net/pf.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
retrieving revision 1.1047
diff -u -p -r1.1047 pf.c
--- sys/net/pf.c 22 Nov 2017 12:28:49 -0000 1.1047
+++ sys/net/pf.c 27 Nov 2017 23:25:27 -0000
@@ -1380,7 +1380,8 @@ pf_remove_divert_state(struct pf_state_k
TAILQ_FOREACH(si, &sk->states, entry) {
if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr &&
- si->s->rule.ptr->divert.port) {
+ (si->s->rule.ptr->divert.type == PF_DIVERT_TO ||
+ si->s->rule.ptr->divert.type == PF_DIVERT_REPLY)) {
pf_remove_state(si->s);
break;
}
@@ -6981,18 +6982,21 @@ done:
if (pd.destchg && pd.dir == PF_OUT)
pd.m->m_pkthdr.pf.flags |= PF_TAG_REROUTE;
- if (pd.dir == PF_IN && action == PF_PASS && r->divert.port) {
+ if (pd.dir == PF_IN && action == PF_PASS &&
+ (r->divert.type == PF_DIVERT_TO ||
+ r->divert.type == PF_DIVERT_REPLY)) {
struct pf_divert *divert;
if ((divert = pf_get_divert(pd.m))) {
pd.m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED;
+ divert->addr = r->divert.addr;
divert->port = r->divert.port;
divert->rdomain = pd.rdomain;
- divert->addr = r->divert.addr;
+ divert->type = r->divert.type;
}
}
- if (action == PF_PASS && r->divert_packet.port)
+ if (action == PF_PASS && r->divert.type == PF_DIVERT_PACKET)
action = PF_DIVERT;
#if NPFLOG > 0
@@ -7023,13 +7027,12 @@ done:
case PF_DIVERT:
switch (pd.af) {
case AF_INET:
- if (!divert_packet(pd.m, pd.dir, r->divert_packet.port))
+ if (!divert_packet(pd.m, pd.dir, r->divert.port))
pd.m = NULL;
break;
#ifdef INET6
case AF_INET6:
- if (!divert6_packet(pd.m, pd.dir,
- r->divert_packet.port))
+ if (!divert6_packet(pd.m, pd.dir, r->divert.port))
pd.m = NULL;
break;
#endif /* INET6 */
Index: sys/net/pf_ioctl.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_ioctl.c,v
retrieving revision 1.325
diff -u -p -r1.325 pf_ioctl.c
--- sys/net/pf_ioctl.c 13 Nov 2017 11:30:11 -0000 1.325
+++ sys/net/pf_ioctl.c 27 Nov 2017 23:25:27 -0000
@@ -2796,8 +2796,7 @@ pf_rule_copyin(struct pf_rule *from, str
to->flush = from->flush;
to->divert.addr = from->divert.addr;
to->divert.port = from->divert.port;
- to->divert_packet.addr = from->divert_packet.addr;
- to->divert_packet.port = from->divert_packet.port;
+ to->divert.type = from->divert.type;
to->prio = from->prio;
to->set_prio[0] = from->set_prio[0];
to->set_prio[1] = from->set_prio[1];
Index: sys/net/pfvar.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfvar.h,v
retrieving revision 1.468
diff -u -p -r1.468 pfvar.h
--- sys/net/pfvar.h 27 Nov 2017 23:21:50 -0000 1.468
+++ sys/net/pfvar.h 27 Nov 2017 23:25:27 -0000
@@ -590,7 +590,8 @@ struct pf_rule {
struct {
struct pf_addr addr;
u_int16_t port;
- } divert, divert_packet;
+ u_int8_t type;
+ } divert;
SLIST_ENTRY(pf_rule) gcle;
struct pf_ruleset *ruleset;
@@ -1394,6 +1395,7 @@ struct pf_divert {
struct pf_addr addr;
u_int16_t port;
u_int16_t rdomain;
+ u_int8_t type;
};
enum pf_divert_types {
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.106
diff -u -p -r1.106 raw_ip.c
--- sys/netinet/raw_ip.c 20 Nov 2017 10:35:24 -0000 1.106
+++ sys/netinet/raw_ip.c 27 Nov 2017 23:25:27 -0000
@@ -149,7 +149,7 @@ rip_input(struct mbuf **mp, int *offp, i
/* XXX rdomain support */
if ((divert = pf_find_divert(m)) == NULL)
continue;
- if (!divert->addr.v4.s_addr)
+ if (divert->type == PF_DIVERT_REPLY)
goto divert_reply;
if (inp->inp_laddr.s_addr != divert->addr.v4.s_addr)
continue;
Index: sys/netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.123
diff -u -p -r1.123 raw_ip6.c
--- sys/netinet6/raw_ip6.c 20 Nov 2017 10:35:24 -0000 1.123
+++ sys/netinet6/raw_ip6.c 27 Nov 2017 23:25:27 -0000
@@ -152,7 +152,7 @@ rip6_input(struct mbuf **mp, int *offp,
/* XXX rdomain support */
if ((divert = pf_find_divert(m)) == NULL)
continue;
- if (IN6_IS_ADDR_UNSPECIFIED(&divert->addr.v6))
+ if (divert->type == PF_DIVERT_REPLY)
goto divert_reply;
if (!IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6,
&divert->addr.v6))
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.667
diff -u -p -r1.667 parse.y
--- sbin/pfctl/parse.y 27 Nov 2017 23:21:50 -0000 1.667
+++ sbin/pfctl/parse.y 27 Nov 2017 23:32:44 -0000
@@ -4084,7 +4084,7 @@ rule_consistent(struct pf_rule *r, int a
/* Basic rule sanity check. */
switch (r->action) {
case PF_MATCH:
- if (r->divert.port) {
+ if (r->divert.type != PF_DIVERT_NONE) {
yyerror("divert is not supported on match rules");
problems++;
}
@@ -4445,16 +4445,18 @@ expand_divertspec(struct pf_rule *r, str
r->divert.addr = ds->addr->addr.v.a.addr;
}
r->divert.port = ds->port;
+ r->divert.type = ds->type;
return (0);
case PF_DIVERT_REPLY:
if (r->direction == PF_IN) {
yyerror("divert-reply used with incoming rule");
return (1);
}
- r->divert.port = 1; /* some random value */
+ r->divert.type = ds->type;
return (0);
case PF_DIVERT_PACKET:
- r->divert_packet.port = ds->port;
+ r->divert.port = ds->port;
+ r->divert.type = ds->type;
return (0);
}
return (1);
Index: sbin/pfctl/pfctl_parser.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.317
diff -u -p -r1.317 pfctl_parser.c
--- sbin/pfctl/pfctl_parser.c 13 Nov 2017 11:30:11 -0000 1.317
+++ sbin/pfctl/pfctl_parser.c 27 Nov 2017 23:32:44 -0000
@@ -1077,24 +1077,31 @@ print_rule(struct pf_rule *r, const char
}
if (r->rtableid != -1)
printf(" rtable %u", r->rtableid);
- if (r->divert.port) {
- if (PF_AZERO(&r->divert.addr, AF_INET6)) {
- printf(" divert-reply");
- } else {
- /* XXX cut&paste from print_addr */
- char buf[48];
+ switch (r->divert.type) {
+ case PF_DIVERT_NONE:
+ break;
+ case PF_DIVERT_TO: {
+ /* XXX cut&paste from print_addr */
+ char buf[48];
- printf(" divert-to ");
- if (inet_ntop(r->af, &r->divert.addr, buf,
- sizeof(buf)) == NULL)
- printf("?");
- else
- printf("%s", buf);
- printf(" port %u", ntohs(r->divert.port));
- }
+ printf(" divert-to ");
+ if (inet_ntop(r->af, &r->divert.addr, buf, sizeof(buf)) == NULL)
+ printf("?");
+ else
+ printf("%s", buf);
+ printf(" port %u", ntohs(r->divert.port));
+ break;
+ }
+ case PF_DIVERT_REPLY:
+ printf(" divert-reply");
+ break;
+ case PF_DIVERT_PACKET:
+ printf(" divert-packet port %u", ntohs(r->divert.port));
+ break;
+ default:
+ printf(" divert ???");
+ break;
}
- if (r->divert_packet.port)
- printf(" divert-packet port %u", ntohs(r->divert_packet.port));
if (!anchor_call[0] && r->nat.addr.type != PF_ADDR_NONE &&
r->rule_flag & PFRULE_AFTO) {