Projet

Général

Profil

Télécharger (4,38 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / killifstates.RELENG_10.diff @ 4ab3b90b

1
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
2
index 1e957f6..2903e32 100644
3
--- a/sbin/pfctl/pfctl.c
4
+++ b/sbin/pfctl/pfctl.c
5
@@ -124,6 +124,8 @@ int		 src_node_killers;
6
 char		*src_node_kill[2];
7
 int		 state_killers;
8
 char		*state_kill[2];
9
+int		 if_kill;
10
+char		*if_gw_kill;
11
 int		 loadopt;
12
 int		 altqsupport;
13
 
14
@@ -389,10 +391,46 @@ pfctl_clear_states(int dev, const char *iface, int opts)
15
 	    sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
16
 		errx(1, "invalid interface: %s", iface);
17
 
18
-	if (ioctl(dev, DIOCCLRSTATES, &psk))
19
-		err(1, "DIOCCLRSTATES");
20
-	if ((opts & PF_OPT_QUIET) == 0)
21
-		fprintf(stderr, "%d states cleared\n", psk.psk_killed);
22
+	if (if_kill) {
23
+		struct addrinfo *res, *resp;
24
+		u_int killed;
25
+		int ret_ga;
26
+
27
+		if ((ret_ga = getaddrinfo(if_gw_kill, NULL, NULL, &res))) {
28
+			errx(1, "getaddrinfo: %s", gai_strerror(ret_ga));
29
+			/* NOTREACHED */
30
+		}
31
+		killed = 0;
32
+		for (resp = res; resp; resp = resp->ai_next) {
33
+			if (resp->ai_addr == NULL)
34
+				continue;
35
+
36
+			psk.psk_af = resp->ai_family;
37
+
38
+			if (psk.psk_af == AF_INET)
39
+				psk.psk_src.addr.v.a.addr.v4 =
40
+					((struct sockaddr_in *)resp->ai_addr)->sin_addr;
41
+			else if (psk.psk_af == AF_INET6)
42
+				psk.psk_src.addr.v.a.addr.v6 =
43
+					((struct sockaddr_in6 *)resp->ai_addr)->
44
+					sin6_addr;
45
+			else
46
+				errx(1, "Unknown address family %d", psk.psk_af);
47
+
48
+			if (ioctl(dev, DIOCCLRSTATES, &psk))
49
+				err(1, "DIOCCLRSTATES");
50
+			if ((opts & PF_OPT_QUIET) == 0)
51
+				killed += psk.psk_af;
52
+		}
53
+		if ((opts & PF_OPT_QUIET) == 0)
54
+			fprintf(stderr, "%d states cleared\n", killed);
55
+	} else {
56
+		if (ioctl(dev, DIOCCLRSTATES, &psk))
57
+			err(1, "DIOCCLRSTATES");
58
+		if ((opts & PF_OPT_QUIET) == 0)
59
+			fprintf(stderr, "%d states cleared\n", psk.psk_af);
60
+	}
61
+
62
 	return (0);
63
 }
64
 
65
@@ -2024,7 +2062,7 @@ main(int argc, char *argv[])
66
 		usage();
67
 
68
 	while ((ch = getopt(argc, argv,
69
-	    "a:AdD:eqf:F:ghi:k:K:mnNOo:Pp:rRs:t:T:vx:y:z")) != -1) {
70
+	    "a:AdD:eqf:F:gG:hi:k:K:mnNOo:Pp:rRs:t:T:vx:y:z")) != -1) {
71
 		switch (ch) {
72
 		case 'a':
73
 			anchoropt = optarg;
74
@@ -2093,6 +2131,16 @@ main(int argc, char *argv[])
75
 		case 'g':
76
 			opts |= PF_OPT_DEBUG;
77
 			break;
78
+		case 'G':
79
+			if (if_kill) {
80
+				warnx("can only specify -b twice");
81
+				usage();
82
+				/* NOTREACHED */
83
+			}
84
+			if_gw_kill = optarg;
85
+			if_kill++;
86
+			mode = O_RDWR;
87
+			break;
88
 		case 'A':
89
 			loadopt |= PFCTL_FLAG_ALTQ;
90
 			break;
91
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
92
index a4134ca..cb38fcb 100644
93
--- a/sys/netpfil/pf/pf.c
94
+++ b/sys/netpfil/pf/pf.c
95
@@ -337,8 +337,8 @@ VNET_DEFINE(struct pf_limit, pf_limits[PF_LIMIT_MAX]);
96
 			return (PF_PASS);				\
97
 	} while (0)
98
 
99
-#define	BOUND_IFACE(r, k) \
100
-	((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all
101
+#define	BOUND_IFACE(r, k) 	k
102
+	/* ((r)->rule_flag & PFRULE_IFBOUND) ? (k) : V_pfi_all */
103
 
104
 #define	STATE_INC_COUNTERS(s)						\
105
 	do {								\
106
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
107
index 4c0f1f5..1b94992 100644
108
--- a/sys/netpfil/pf/pf_ioctl.c
109
+++ b/sys/netpfil/pf/pf_ioctl.c
110
@@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$");
111
 #include <net/route.h>
112
 #include <net/pfil.h>
113
 #include <net/pfvar.h>
114
+#define TCPSTATES
115
+#include <netinet/tcp_fsm.h>
116
 #include <net/if_pfsync.h>
117
 #include <net/if_pflog.h>
118
 
119
@@ -1598,6 +1600,7 @@ DIOCCHANGERULE_error:
120
 
121
 	case DIOCCLRSTATES: {
122
 		struct pf_state		*s;
123
+		struct pf_state_key	*sk;
124
 		struct pfioc_state_kill *psk = (struct pfioc_state_kill *)addr;
125
 		u_int			 i, killed = 0;
126
 
127
@@ -1607,6 +1610,7 @@ DIOCCHANGERULE_error:
128
 relock_DIOCCLRSTATES:
129
 			PF_HASHROW_LOCK(ih);
130
 			LIST_FOREACH(s, &ih->states, entry)
131
+				sk = s->key[PF_SK_WIRE];
132
 				if (!psk->psk_ifname[0] ||
133
 				    !strcmp(psk->psk_ifname,
134
 				    s->kif->pfik_name)) {
135
@@ -1618,6 +1622,20 @@ relock_DIOCCLRSTATES:
136
 					pf_unlink_state(s, PF_ENTER_LOCKED);
137
 					killed++;
138
 					goto relock_DIOCCLRSTATES;
139
+				} else if (sk->af == psk->psk_af &&
140
+				    !PF_AZERO(&psk->psk_src.addr.v.a.addr, psk->psk_af) &&
141
+			    	    !PF_AZERO(&s->rt_addr, sk->af) &&
142
+				    PF_AEQ(&psk->psk_src.addr.v.a.addr, &s->rt_addr, sk->af)) {
143
+					if (sk->proto == IPPROTO_TCP)
144
+						s->src.state = PF_TCPS_PROXY_DST; /* XXX: Hack to send a RST back to the host */
145
+					/*
146
+					 * Don't send out individual
147
+					 * delete messages.
148
+					 */
149
+					s->state_flags |= PFSTATE_NOSYNC;
150
+					pf_unlink_state(s, PF_ENTER_LOCKED);
151
+					killed++;
152
+					goto relock_DIOCCLRSTATES;
153
 				}
154
 			PF_HASHROW_UNLOCK(ih);
155
 		}
(29-29/67)