kernel - Enable busmaster on bridges (BIOS might not)
[dragonfly.git] / sys / net / ipfw3 / ip_fw3_set.c
blobb50e9cf98cac713cbee76a3cc315f335d57a1048
1 /*
2 * Copyright (c) 2014 - 2018 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Bill Yuan <bycn82@dragonflybsd.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
35 #include "opt_ipfw.h"
36 #include "opt_inet.h"
37 #ifndef INET
38 #error IPFIREWALL3 requires INET.
39 #endif /* INET */
41 #include <sys/param.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/mbuf.h>
45 #include <sys/socketvar.h>
46 #include <sys/sysctl.h>
47 #include <sys/systimer.h>
48 #include <sys/in_cksum.h>
49 #include <sys/systm.h>
50 #include <sys/proc.h>
51 #include <sys/socket.h>
52 #include <sys/syslog.h>
53 #include <sys/ucred.h>
54 #include <sys/lock.h>
55 #include <sys/mplock2.h>
57 #include <net/ethernet.h>
58 #include <net/netmsg2.h>
59 #include <net/netisr2.h>
60 #include <net/route.h>
61 #include <net/if.h>
63 #include <netinet/in.h>
64 #include <netinet/ip.h>
65 #include <netinet/ip_icmp.h>
66 #include <netinet/tcp.h>
67 #include <netinet/tcp_timer.h>
68 #include <netinet/tcp_var.h>
69 #include <netinet/tcpip.h>
70 #include <netinet/udp.h>
71 #include <netinet/udp_var.h>
72 #include <netinet/in_systm.h>
73 #include <netinet/in_var.h>
74 #include <netinet/in_pcb.h>
75 #include <netinet/ip_var.h>
76 #include <netinet/ip_divert.h>
77 #include <net/ipfw3/ip_fw.h>
79 #include "ip_fw3.h"
80 #include "ip_fw3_set.h"
83 extern struct ipfw3_context *fw3_ctx[MAXCPU];
85 void
86 move_set_dispatch(netmsg_t smsg)
88 struct netmsg_sets *msg = (struct netmsg_sets *)smsg;
89 struct ipfw3_context *ctx = fw3_ctx[mycpuid];
90 struct ip_fw *rule;
91 for (rule = ctx->rules; rule; rule = rule->next) {
92 if (rule->set == msg->set_from)
93 rule->set = msg->set_to;
95 netisr_forwardmsg_all(&smsg->base, mycpuid + 1);
98 int
99 ip_fw3_ctl_set_move_set(struct sockopt *sopt)
101 struct ipfw3_context *ctx;
102 struct netmsg_sets msg;
103 int *set1, *set2;
105 ctx = fw3_ctx[mycpuid];
106 set1 =(int *)sopt->sopt_val;
107 set2 = set1 + 1;
108 if (*set1 > 0 && *set1 < 32 && *set2 > 0 && *set2 < 32) {
109 bzero(&msg, sizeof(msg));
110 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
111 0, move_set_dispatch);
112 msg.set_from = *set1;
113 msg.set_to = *set2;
115 netisr_domsg(&msg.base, 0);
117 return 0;
120 void
121 move_rule_dispatch(netmsg_t smsg)
123 struct netmsg_sets *msg = (struct netmsg_sets *)smsg;
124 struct ipfw3_context *ctx = fw3_ctx[mycpuid];
125 struct ip_fw *rule;
126 for (rule = ctx->rules; rule; rule = rule->next) {
127 if (rule->rulenum == msg->rule_num)
128 rule->set = msg->set_to;
130 netisr_forwardmsg_all(&smsg->base, mycpuid + 1);
134 ip_fw3_ctl_set_move_rule(struct sockopt *sopt)
136 struct ipfw3_context *ctx;
137 struct netmsg_sets msg;
138 int *rule_num, *set;
140 ctx = fw3_ctx[mycpuid];
141 rule_num =(int *)sopt->sopt_val;
142 set = rule_num + 1;
143 if (*rule_num > 0 && *rule_num < 65535 && *set >= 0 && *set < 32) {
144 bzero(&msg, sizeof(msg));
145 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
146 0, move_rule_dispatch);
147 msg.rule_num = *rule_num;
148 msg.set_to = *set;
149 netisr_domsg(&msg.base, 0);
151 return 0;
154 void
155 set_swap_dispatch(netmsg_t smsg)
157 struct netmsg_sets *msg = (struct netmsg_sets *)smsg;
158 struct ipfw3_context *ctx = fw3_ctx[mycpuid];
159 struct ip_fw *rule;
161 for (rule = ctx->rules; rule; rule = rule->next) {
162 if (rule->set == msg->set_from)
163 rule->set = msg->set_to;
164 else if (rule->set == msg->set_to)
165 rule->set = msg->set_from;
167 netisr_forwardmsg_all(&smsg->base, mycpuid + 1);
171 ip_fw3_ctl_set_swap(struct sockopt *sopt)
173 struct ipfw3_context *ctx;
174 struct netmsg_sets msg;
175 int *set1, *set2;
177 ctx = fw3_ctx[mycpuid];
178 set1 =(int *)sopt->sopt_val;
179 set2 = set1 + 1;
180 if (*set1 > 0 && *set1 < 32 && *set2 > 0 && *set2 < 32) {
181 bzero(&msg, sizeof(msg));
182 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
183 0, set_swap_dispatch);
184 msg.set_from = *set1;
185 msg.set_to = *set2;
187 netisr_domsg(&msg.base, 0);
189 return 0;
193 ip_fw3_ctl_set_toggle(struct sockopt *sopt)
195 struct ipfw3_context *ctx;
196 int *num;
198 ctx = fw3_ctx[mycpuid];
200 num =(int *)sopt->sopt_val;
201 if (*num > 0 && *num < 32) {
202 ctx->sets = ctx->sets ^ (1 << *num);
204 return 0;
208 ip_fw3_ctl_set_get(struct sockopt *sopt)
210 struct ipfw3_context *ctx;
212 ctx = fw3_ctx[mycpuid];
214 bcopy(&ctx->sets, sopt->sopt_val, sopt->sopt_valsize);
215 return 0;
218 void
219 set_flush_dispatch(netmsg_t smsg)
221 struct netmsg_sets *msg = (struct netmsg_sets *)smsg;
222 struct ipfw3_context *ctx = fw3_ctx[mycpuid];
223 struct ip_fw *prev, *rule;
225 prev = NULL;
226 rule = ctx->rules;
227 while (rule != NULL) {
228 if (rule->set == msg->set_to) {
229 rule = ip_fw3_delete_rule(ctx, prev, rule);
230 } else {
231 prev = rule;
232 rule = rule->next;
235 netisr_forwardmsg_all(&smsg->base, mycpuid + 1);
239 ip_fw3_ctl_set_flush(struct sockopt *sopt)
241 struct netmsg_sets msg;
242 int *num;
244 num =(int *)sopt->sopt_val;
245 if (*num > 0 && *num < 32) {
246 bzero(&msg, sizeof(msg));
247 netmsg_init(&msg.base, NULL, &curthread->td_msgport,
248 0, set_flush_dispatch);
249 msg.set_to = *num;
251 netisr_domsg(&msg.base, 0);
253 return 0;
257 ip_fw3_ctl_set_sockopt(struct sockopt *sopt)
259 int error = 0;
260 switch (sopt->sopt_name) {
261 case IP_FW_SET_GET:
262 error = ip_fw3_ctl_set_get(sopt);
263 break;
264 case IP_FW_SET_TOGGLE:
265 error = ip_fw3_ctl_set_toggle(sopt);
266 break;
267 case IP_FW_SET_SWAP:
268 error = ip_fw3_ctl_set_swap(sopt);
269 break;
270 case IP_FW_SET_MOVE_RULE:
271 error = ip_fw3_ctl_set_move_rule(sopt);
272 break;
273 case IP_FW_SET_MOVE_SET:
274 error = ip_fw3_ctl_set_move_set(sopt);
275 break;
276 case IP_FW_SET_FLUSH:
277 error = ip_fw3_ctl_set_flush(sopt);
278 break;
279 default:
280 kprintf("ipfw3 set invalid socket option %d\n",
281 sopt->sopt_name);
283 return error;