1 /* $NetBSD: mpls_proto.c,v 1.33 2022/09/03 02:24:59 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Mihai Chelaru <kefren@NetBSD.org>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.33 2022/09/03 02:24:59 thorpej Exp $");
34
35 #ifdef _KERNEL_OPT
36 #include "opt_inet.h"
37 #include "opt_mbuftrace.h"
38 #endif
39
40 #include <sys/param.h>
41 #include <sys/socket.h>
42 #include <sys/protosw.h>
43 #include <sys/domain.h>
44 #include <sys/socketvar.h>
45 #include <sys/sysctl.h>
46
47 #include <net/route.h>
48
49 #include <netmpls/mpls.h>
50 #include <netmpls/mpls_var.h>
51
52 #define MPLS_MAXQLEN 256
53 pktqueue_t * mpls_pktq __read_mostly;
54
55 static int mpls_attach(struct socket *, int);
56 static void sysctl_net_mpls_setup(struct sysctllog **);
57
58 #ifdef MBUFTRACE
59 struct mowner mpls_owner = MOWNER_INIT("MPLS", "");
60 #endif
61
62 int mpls_defttl = 255;
63 int mpls_mapttl_inet = 1;
64 int mpls_mapttl_inet6 = 1;
65 int mpls_icmp_respond = 0;
66 int mpls_forwarding = 0;
67 int mpls_frame_accept = 0;
68 int mpls_mapprec_inet = 1;
69 int mpls_mapclass_inet6 = 1;
70 int mpls_rfc4182 = 1;
71
72 void mpls_init(void)
73 {
74 #ifdef MBUFTRACE
75 MOWNER_ATTACH(&mpls_owner);
76 #endif
77 mpls_pktq = pktq_create(MPLS_MAXQLEN, mplsintr, NULL);
78 KASSERT(mpls_pktq != NULL);
79
80 sysctl_net_mpls_setup(NULL);
81 }
82
83 static int
84 mpls_attach(struct socket *so, int proto)
85 {
86 int error = EOPNOTSUPP;
87
88 sosetlock(so);
89 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
90 error = soreserve(so, 8192, 8192);
91 }
92 return error;
93 }
94
95 static void
96 mpls_detach(struct socket *so)
97 {
98 }
99
100 static int
101 mpls_accept(struct socket *so, struct sockaddr *nam)
102 {
103 KASSERT(solocked(so));
104
105 return EOPNOTSUPP;
106 }
107
108 static int
109 mpls_bind(struct socket *so, struct sockaddr *nam, struct lwp *l)
110 {
111 KASSERT(solocked(so));
112
113 return EOPNOTSUPP;
114 }
115
116 static int
117 mpls_listen(struct socket *so, struct lwp *l)
118 {
119 KASSERT(solocked(so));
120
121 return EOPNOTSUPP;
122 }
123
124 static int
125 mpls_connect(struct socket *so, struct sockaddr *nam, struct lwp *l)
126 {
127 KASSERT(solocked(so));
128
129 return EOPNOTSUPP;
130 }
131
132 static int
133 mpls_connect2(struct socket *so, struct socket *so2)
134 {
135 KASSERT(solocked(so));
136
137 return EOPNOTSUPP;
138 }
139
140 static int
141 mpls_disconnect(struct socket *so)
142 {
143 KASSERT(solocked(so));
144
145 return EOPNOTSUPP;
146 }
147
148 static int
149 mpls_shutdown(struct socket *so)
150 {
151 KASSERT(solocked(so));
152
153 return EOPNOTSUPP;
154 }
155
156 static int
157 mpls_abort(struct socket *so)
158 {
159 KASSERT(solocked(so));
160
161 return EOPNOTSUPP;
162 }
163
164 static int
165 mpls_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
166 {
167 return EOPNOTSUPP;
168 }
169
170 static int
171 mpls_stat(struct socket *so, struct stat *ub)
172 {
173 KASSERT(solocked(so));
174
175 return EOPNOTSUPP;
176 }
177
178 static int
179 mpls_peeraddr(struct socket *so, struct sockaddr *nam)
180 {
181 KASSERT(solocked(so));
182
183 return EOPNOTSUPP;
184 }
185
186 static int
187 mpls_sockaddr(struct socket *so, struct sockaddr *nam)
188 {
189 KASSERT(solocked(so));
190
191 return EOPNOTSUPP;
192 }
193
194 static int
195 mpls_rcvd(struct socket *so, int flags, struct lwp *l)
196 {
197 KASSERT(solocked(so));
198
199 return EOPNOTSUPP;
200 }
201
202 static int
203 mpls_recvoob(struct socket *so, struct mbuf *m, int flags)
204 {
205 KASSERT(solocked(so));
206
207 return EOPNOTSUPP;
208 }
209
210 static int
211 mpls_send(struct socket *so, struct mbuf *m, struct sockaddr *nam,
212 struct mbuf *control, struct lwp *l)
213 {
214 KASSERT(solocked(so));
215
216 return EOPNOTSUPP;
217 }
218
219 static int
220 mpls_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
221 {
222 KASSERT(solocked(so));
223
224 m_freem(m);
225 m_freem(control);
226
227 return EOPNOTSUPP;
228 }
229
230 static int
231 mpls_purgeif(struct socket *so, struct ifnet *ifp)
232 {
233
234 return EOPNOTSUPP;
235 }
236
237 /*
238 * Sysctl for MPLS variables.
239 */
240 static void
241 sysctl_net_mpls_setup(struct sysctllog **clog)
242 {
243 const struct sysctlnode *mpls_node;
244
245 sysctl_createv(clog, 0, NULL, &mpls_node,
246 CTLFLAG_PERMANENT,
247 CTLTYPE_NODE, "mpls", NULL,
248 NULL, 0, NULL, 0,
249 CTL_NET, PF_MPLS, CTL_EOL);
250
251 sysctl_createv(clog, 0, NULL, NULL,
252 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
253 CTLTYPE_INT, "ttl",
254 SYSCTL_DESCR("Default TTL"),
255 NULL, 0, &mpls_defttl, 0,
256 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
257 sysctl_createv(clog, 0, NULL, NULL,
258 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
259 CTLTYPE_INT, "forwarding",
260 SYSCTL_DESCR("MPLS forwarding"),
261 NULL, 0, &mpls_forwarding, 0,
262 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
263 sysctl_createv(clog, 0, NULL, NULL,
264 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
265 CTLTYPE_INT, "accept",
266 SYSCTL_DESCR("Accept MPLS Frames"),
267 NULL, 0, &mpls_frame_accept, 0,
268 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
269
270 pktq_sysctl_setup(mpls_pktq, clog, mpls_node, CTL_CREATE);
271
272 sysctl_createv(clog, 0, NULL, NULL,
273 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
274 CTLTYPE_INT, "rfc4182",
275 SYSCTL_DESCR("RFC 4182 conformance"),
276 NULL, 0, &mpls_rfc4182, 0,
277 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
278 #ifdef INET
279 sysctl_createv(clog, 0, NULL, NULL,
280 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
281 CTLTYPE_INT, "inet_mapttl",
282 SYSCTL_DESCR("Map IP TTL"),
283 NULL, 0, &mpls_mapttl_inet, 0,
284 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
285 sysctl_createv(clog, 0, NULL, NULL,
286 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
287 CTLTYPE_INT, "inet_map_prec",
288 SYSCTL_DESCR("Map IP Prec"),
289 NULL, 0, &mpls_mapprec_inet, 0,
290 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
291 sysctl_createv(clog, 0, NULL, NULL,
292 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
293 CTLTYPE_INT, "icmp_respond",
294 SYSCTL_DESCR("Emit ICMP packets on errors"),
295 NULL, 0, &mpls_icmp_respond, 0,
296 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
297 #endif
298 #ifdef INET6
299 sysctl_createv(clog, 0, NULL, NULL,
300 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
301 CTLTYPE_INT, "inet6_mapttl",
302 SYSCTL_DESCR("Map IP6 TTL"),
303 NULL, 0, &mpls_mapttl_inet6, 0,
304 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
305 sysctl_createv(clog, 0, NULL, NULL,
306 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
307 CTLTYPE_INT, "inet6_map_prec",
308 SYSCTL_DESCR("Map IP6 class"),
309 NULL, 0, &mpls_mapclass_inet6, 0,
310 CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
311 #endif
312 }
313
314 DOMAIN_DEFINE(mplsdomain);
315
316 PR_WRAP_USRREQS(mpls)
317 #define mpls_attach mpls_attach_wrapper
318 #define mpls_detach mpls_detach_wrapper
319 #define mpls_accept mpls_accept_wrapper
320 #define mpls_bind mpls_bind_wrapper
321 #define mpls_listen mpls_listen_wrapper
322 #define mpls_connect mpls_connect_wrapper
323 #define mpls_connect2 mpls_connect2_wrapper
324 #define mpls_disconnect mpls_disconnect_wrapper
325 #define mpls_shutdown mpls_shutdown_wrapper
326 #define mpls_abort mpls_abort_wrapper
327 #define mpls_ioctl mpls_ioctl_wrapper
328 #define mpls_stat mpls_stat_wrapper
329 #define mpls_peeraddr mpls_peeraddr_wrapper
330 #define mpls_sockaddr mpls_sockaddr_wrapper
331 #define mpls_rcvd mpls_rcvd_wrapper
332 #define mpls_recvoob mpls_recvoob_wrapper
333 #define mpls_send mpls_send_wrapper
334 #define mpls_sendoob mpls_sendoob_wrapper
335 #define mpls_purgeif mpls_purgeif_wrapper
336
337 static const struct pr_usrreqs mpls_usrreqs = {
338 .pr_attach = mpls_attach,
339 .pr_detach = mpls_detach,
340 .pr_accept = mpls_accept,
341 .pr_bind = mpls_bind,
342 .pr_listen = mpls_listen,
343 .pr_connect = mpls_connect,
344 .pr_connect2 = mpls_connect2,
345 .pr_disconnect = mpls_disconnect,
346 .pr_shutdown = mpls_shutdown,
347 .pr_abort = mpls_abort,
348 .pr_ioctl = mpls_ioctl,
349 .pr_stat = mpls_stat,
350 .pr_peeraddr = mpls_peeraddr,
351 .pr_sockaddr = mpls_sockaddr,
352 .pr_rcvd = mpls_rcvd,
353 .pr_recvoob = mpls_recvoob,
354 .pr_send = mpls_send,
355 .pr_sendoob = mpls_sendoob,
356 .pr_purgeif = mpls_purgeif,
357 };
358
359 const struct protosw mplssw[] = {
360 { .pr_domain = &mplsdomain,
361 .pr_init = mpls_init,
362 },
363 {
364 .pr_type = SOCK_DGRAM,
365 .pr_domain = &mplsdomain,
366 .pr_flags = PR_ATOMIC | PR_ADDR,
367 .pr_usrreqs = &mpls_usrreqs,
368 },
369 {
370 .pr_type = SOCK_RAW,
371 .pr_domain = &mplsdomain,
372 .pr_flags = PR_ATOMIC | PR_ADDR,
373 .pr_usrreqs = &mpls_usrreqs,
374 },
375 };
376
377 struct domain mplsdomain = {
378 .dom_family = PF_MPLS,
379 .dom_name = "MPLS",
380 .dom_init = NULL,
381 .dom_externalize = NULL,
382 .dom_dispose = NULL,
383 .dom_protosw = mplssw,
384 .dom_protoswNPROTOSW = &mplssw[__arraycount(mplssw)],
385 .dom_rtattach = rt_inithead,
386 .dom_rtoffset = offsetof(struct sockaddr_mpls, smpls_addr) << 3,
387 .dom_maxrtkey = sizeof(union mpls_shim),
388 .dom_ifattach = NULL,
389 .dom_ifdetach = NULL,
390 .dom_link = { NULL },
391 .dom_mowner = MOWNER_INIT("MPLS", ""),
392 .dom_sa_cmpofs = offsetof(struct sockaddr_mpls, smpls_addr),
393 .dom_sa_cmplen = sizeof(union mpls_shim),
394 };
Cache object: 160c5b07df2e95d6916b7239dc3ce6cf
|