xref: /netbsd-src/sys/netmpls/mpls_proto.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /*	$NetBSD: mpls_proto.c,v 1.32 2019/01/28 12:53:01 martin 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.32 2019/01/28 12:53:01 martin 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 struct ifqueue mplsintrq;
53 
54 static int mpls_attach(struct socket *, int);
55 static void sysctl_net_mpls_setup(struct sysctllog **);
56 
57 #ifdef MBUFTRACE
58 struct mowner mpls_owner = MOWNER_INIT("MPLS", "");
59 #endif
60 
61 int mpls_defttl = 255;
62 int mpls_mapttl_inet = 1;
63 int mpls_mapttl_inet6 = 1;
64 int mpls_icmp_respond = 0;
65 int mpls_forwarding = 0;
66 int mpls_frame_accept = 0;
67 int mpls_mapprec_inet = 1;
68 int mpls_mapclass_inet6 = 1;
69 int mpls_rfc4182 = 1;
70 
71 void mpls_init(void)
72 {
73 #ifdef MBUFTRACE
74 	MOWNER_ATTACH(&mpls_owner);
75 #endif
76 	memset(&mplsintrq, 0, sizeof(mplsintrq));
77 	mplsintrq.ifq_maxlen = 256;
78 	IFQ_LOCK_INIT(&mplsintrq);
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 
244         sysctl_createv(clog, 0, NULL, NULL,
245                        CTLFLAG_PERMANENT,
246                        CTLTYPE_NODE, "mpls", NULL,
247                        NULL, 0, NULL, 0,
248                        CTL_NET, PF_MPLS, CTL_EOL);
249 
250         sysctl_createv(clog, 0, NULL, NULL,
251                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
252                        CTLTYPE_INT, "ttl",
253                        SYSCTL_DESCR("Default TTL"),
254                        NULL, 0, &mpls_defttl, 0,
255                        CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
256 	sysctl_createv(clog, 0, NULL, NULL,
257 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
258 		       CTLTYPE_INT, "forwarding",
259 		       SYSCTL_DESCR("MPLS forwarding"),
260 		       NULL, 0, &mpls_forwarding, 0,
261 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
262 	sysctl_createv(clog, 0, NULL, NULL,
263 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
264 		       CTLTYPE_INT, "accept",
265 		       SYSCTL_DESCR("Accept MPLS Frames"),
266 		       NULL, 0, &mpls_frame_accept, 0,
267 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
268 	sysctl_createv(clog, 0, NULL, NULL,
269 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
270 		       CTLTYPE_INT, "ifq_len",
271 		       SYSCTL_DESCR("MPLS queue length"),
272 		       NULL, 0, &mplsintrq.ifq_maxlen, 0,
273 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
274 	sysctl_createv(clog, 0, NULL, NULL,
275 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
276 		       CTLTYPE_INT, "rfc4182",
277 		       SYSCTL_DESCR("RFC 4182 conformance"),
278 		       NULL, 0, &mpls_rfc4182, 0,
279 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
280 #ifdef INET
281 	sysctl_createv(clog, 0, NULL, NULL,
282 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
283 		       CTLTYPE_INT, "inet_mapttl",
284 		       SYSCTL_DESCR("Map IP TTL"),
285 		       NULL, 0, &mpls_mapttl_inet, 0,
286 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
287 	sysctl_createv(clog, 0, NULL, NULL,
288 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
289 		       CTLTYPE_INT, "inet_map_prec",
290 		       SYSCTL_DESCR("Map IP Prec"),
291 		       NULL, 0, &mpls_mapprec_inet, 0,
292 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
293 	sysctl_createv(clog, 0, NULL, NULL,
294 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
295 		       CTLTYPE_INT, "icmp_respond",
296 		       SYSCTL_DESCR("Emit ICMP packets on errors"),
297 		       NULL, 0, &mpls_icmp_respond, 0,
298 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
299 #endif
300 #ifdef INET6
301 	sysctl_createv(clog, 0, NULL, NULL,
302 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
303 		       CTLTYPE_INT, "inet6_mapttl",
304 		       SYSCTL_DESCR("Map IP6 TTL"),
305 		       NULL, 0, &mpls_mapttl_inet6, 0,
306 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
307 	sysctl_createv(clog, 0, NULL, NULL,
308 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
309 		       CTLTYPE_INT, "inet6_map_prec",
310 		       SYSCTL_DESCR("Map IP6 class"),
311 		       NULL, 0, &mpls_mapclass_inet6, 0,
312 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
313 #endif
314 }
315 
316 DOMAIN_DEFINE(mplsdomain);
317 
318 PR_WRAP_USRREQS(mpls)
319 #define	mpls_attach	mpls_attach_wrapper
320 #define	mpls_detach	mpls_detach_wrapper
321 #define	mpls_accept	mpls_accept_wrapper
322 #define	mpls_bind	mpls_bind_wrapper
323 #define	mpls_listen	mpls_listen_wrapper
324 #define	mpls_connect	mpls_connect_wrapper
325 #define	mpls_connect2	mpls_connect2_wrapper
326 #define	mpls_disconnect	mpls_disconnect_wrapper
327 #define	mpls_shutdown	mpls_shutdown_wrapper
328 #define	mpls_abort	mpls_abort_wrapper
329 #define	mpls_ioctl	mpls_ioctl_wrapper
330 #define	mpls_stat	mpls_stat_wrapper
331 #define	mpls_peeraddr	mpls_peeraddr_wrapper
332 #define	mpls_sockaddr	mpls_sockaddr_wrapper
333 #define	mpls_rcvd	mpls_rcvd_wrapper
334 #define	mpls_recvoob	mpls_recvoob_wrapper
335 #define	mpls_send	mpls_send_wrapper
336 #define	mpls_sendoob	mpls_sendoob_wrapper
337 #define	mpls_purgeif	mpls_purgeif_wrapper
338 
339 static const struct pr_usrreqs mpls_usrreqs = {
340 	.pr_attach	= mpls_attach,
341 	.pr_detach	= mpls_detach,
342 	.pr_accept	= mpls_accept,
343 	.pr_bind	= mpls_bind,
344 	.pr_listen	= mpls_listen,
345 	.pr_connect	= mpls_connect,
346 	.pr_connect2	= mpls_connect2,
347 	.pr_disconnect	= mpls_disconnect,
348 	.pr_shutdown	= mpls_shutdown,
349 	.pr_abort	= mpls_abort,
350 	.pr_ioctl	= mpls_ioctl,
351 	.pr_stat	= mpls_stat,
352 	.pr_peeraddr	= mpls_peeraddr,
353 	.pr_sockaddr	= mpls_sockaddr,
354 	.pr_rcvd	= mpls_rcvd,
355 	.pr_recvoob	= mpls_recvoob,
356 	.pr_send	= mpls_send,
357 	.pr_sendoob	= mpls_sendoob,
358 	.pr_purgeif	= mpls_purgeif,
359 };
360 
361 const struct protosw mplssw[] = {
362 	{	.pr_domain = &mplsdomain,
363 		.pr_init = mpls_init,
364 	},
365 	{
366 		.pr_type = SOCK_DGRAM,
367 		.pr_domain = &mplsdomain,
368 		.pr_flags = PR_ATOMIC | PR_ADDR,
369 		.pr_usrreqs = &mpls_usrreqs,
370 	},
371 	{
372 		.pr_type = SOCK_RAW,
373 		.pr_domain = &mplsdomain,
374 		.pr_flags = PR_ATOMIC | PR_ADDR,
375 		.pr_usrreqs = &mpls_usrreqs,
376 	},
377 };
378 
379 struct domain mplsdomain = {
380 	.dom_family = PF_MPLS,
381 	.dom_name = "MPLS",
382 	.dom_init = NULL,
383 	.dom_externalize = NULL,
384 	.dom_dispose = NULL,
385 	.dom_protosw = mplssw,
386 	.dom_protoswNPROTOSW = &mplssw[__arraycount(mplssw)],
387 	.dom_rtattach = rt_inithead,
388 	.dom_rtoffset = offsetof(struct sockaddr_mpls, smpls_addr) << 3,
389 	.dom_maxrtkey = sizeof(union mpls_shim),
390 	.dom_ifattach = NULL,
391 	.dom_ifdetach = NULL,
392 	.dom_ifqueues = { &mplsintrq, NULL },
393 	.dom_link = { NULL },
394 	.dom_mowner = MOWNER_INIT("MPLS", ""),
395 	.dom_sa_cmpofs = offsetof(struct sockaddr_mpls, smpls_addr),
396 	.dom_sa_cmplen = sizeof(union mpls_shim),
397 };
398