xref: /netbsd-src/sys/netmpls/mpls_proto.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: mpls_proto.c,v 1.31 2017/09/21 07:15:35 ozaki-r 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.31 2017/09/21 07:15:35 ozaki-r 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 	return EOPNOTSUPP;
225 }
226 
227 static int
228 mpls_purgeif(struct socket *so, struct ifnet *ifp)
229 {
230 
231 	return EOPNOTSUPP;
232 }
233 
234 /*
235  * Sysctl for MPLS variables.
236  */
237 static void
238 sysctl_net_mpls_setup(struct sysctllog **clog)
239 {
240 
241         sysctl_createv(clog, 0, NULL, NULL,
242                        CTLFLAG_PERMANENT,
243                        CTLTYPE_NODE, "mpls", NULL,
244                        NULL, 0, NULL, 0,
245                        CTL_NET, PF_MPLS, CTL_EOL);
246 
247         sysctl_createv(clog, 0, NULL, NULL,
248                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
249                        CTLTYPE_INT, "ttl",
250                        SYSCTL_DESCR("Default TTL"),
251                        NULL, 0, &mpls_defttl, 0,
252                        CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
253 	sysctl_createv(clog, 0, NULL, NULL,
254 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
255 		       CTLTYPE_INT, "forwarding",
256 		       SYSCTL_DESCR("MPLS forwarding"),
257 		       NULL, 0, &mpls_forwarding, 0,
258 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
259 	sysctl_createv(clog, 0, NULL, NULL,
260 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
261 		       CTLTYPE_INT, "accept",
262 		       SYSCTL_DESCR("Accept MPLS Frames"),
263 		       NULL, 0, &mpls_frame_accept, 0,
264 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
265 	sysctl_createv(clog, 0, NULL, NULL,
266 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
267 		       CTLTYPE_INT, "ifq_len",
268 		       SYSCTL_DESCR("MPLS queue length"),
269 		       NULL, 0, &mplsintrq.ifq_maxlen, 0,
270 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
271 	sysctl_createv(clog, 0, NULL, NULL,
272 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
273 		       CTLTYPE_INT, "rfc4182",
274 		       SYSCTL_DESCR("RFC 4182 conformance"),
275 		       NULL, 0, &mpls_rfc4182, 0,
276 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
277 #ifdef INET
278 	sysctl_createv(clog, 0, NULL, NULL,
279 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
280 		       CTLTYPE_INT, "inet_mapttl",
281 		       SYSCTL_DESCR("Map IP TTL"),
282 		       NULL, 0, &mpls_mapttl_inet, 0,
283 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
284 	sysctl_createv(clog, 0, NULL, NULL,
285 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
286 		       CTLTYPE_INT, "inet_map_prec",
287 		       SYSCTL_DESCR("Map IP Prec"),
288 		       NULL, 0, &mpls_mapprec_inet, 0,
289 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
290 	sysctl_createv(clog, 0, NULL, NULL,
291 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
292 		       CTLTYPE_INT, "icmp_respond",
293 		       SYSCTL_DESCR("Emit ICMP packets on errors"),
294 		       NULL, 0, &mpls_icmp_respond, 0,
295 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
296 #endif
297 #ifdef INET6
298 	sysctl_createv(clog, 0, NULL, NULL,
299 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
300 		       CTLTYPE_INT, "inet6_mapttl",
301 		       SYSCTL_DESCR("Map IP6 TTL"),
302 		       NULL, 0, &mpls_mapttl_inet6, 0,
303 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
304 	sysctl_createv(clog, 0, NULL, NULL,
305 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
306 		       CTLTYPE_INT, "inet6_map_prec",
307 		       SYSCTL_DESCR("Map IP6 class"),
308 		       NULL, 0, &mpls_mapclass_inet6, 0,
309 		       CTL_NET, PF_MPLS, CTL_CREATE, CTL_EOL);
310 #endif
311 }
312 
313 DOMAIN_DEFINE(mplsdomain);
314 
315 PR_WRAP_USRREQS(mpls)
316 #define	mpls_attach	mpls_attach_wrapper
317 #define	mpls_detach	mpls_detach_wrapper
318 #define	mpls_accept	mpls_accept_wrapper
319 #define	mpls_bind	mpls_bind_wrapper
320 #define	mpls_listen	mpls_listen_wrapper
321 #define	mpls_connect	mpls_connect_wrapper
322 #define	mpls_connect2	mpls_connect2_wrapper
323 #define	mpls_disconnect	mpls_disconnect_wrapper
324 #define	mpls_shutdown	mpls_shutdown_wrapper
325 #define	mpls_abort	mpls_abort_wrapper
326 #define	mpls_ioctl	mpls_ioctl_wrapper
327 #define	mpls_stat	mpls_stat_wrapper
328 #define	mpls_peeraddr	mpls_peeraddr_wrapper
329 #define	mpls_sockaddr	mpls_sockaddr_wrapper
330 #define	mpls_rcvd	mpls_rcvd_wrapper
331 #define	mpls_recvoob	mpls_recvoob_wrapper
332 #define	mpls_send	mpls_send_wrapper
333 #define	mpls_sendoob	mpls_sendoob_wrapper
334 #define	mpls_purgeif	mpls_purgeif_wrapper
335 
336 static const struct pr_usrreqs mpls_usrreqs = {
337 	.pr_attach	= mpls_attach,
338 	.pr_detach	= mpls_detach,
339 	.pr_accept	= mpls_accept,
340 	.pr_bind	= mpls_bind,
341 	.pr_listen	= mpls_listen,
342 	.pr_connect	= mpls_connect,
343 	.pr_connect2	= mpls_connect2,
344 	.pr_disconnect	= mpls_disconnect,
345 	.pr_shutdown	= mpls_shutdown,
346 	.pr_abort	= mpls_abort,
347 	.pr_ioctl	= mpls_ioctl,
348 	.pr_stat	= mpls_stat,
349 	.pr_peeraddr	= mpls_peeraddr,
350 	.pr_sockaddr	= mpls_sockaddr,
351 	.pr_rcvd	= mpls_rcvd,
352 	.pr_recvoob	= mpls_recvoob,
353 	.pr_send	= mpls_send,
354 	.pr_sendoob	= mpls_sendoob,
355 	.pr_purgeif	= mpls_purgeif,
356 };
357 
358 const struct protosw mplssw[] = {
359 	{	.pr_domain = &mplsdomain,
360 		.pr_init = mpls_init,
361 	},
362 	{
363 		.pr_type = SOCK_DGRAM,
364 		.pr_domain = &mplsdomain,
365 		.pr_flags = PR_ATOMIC | PR_ADDR,
366 		.pr_usrreqs = &mpls_usrreqs,
367 	},
368 	{
369 		.pr_type = SOCK_RAW,
370 		.pr_domain = &mplsdomain,
371 		.pr_flags = PR_ATOMIC | PR_ADDR,
372 		.pr_usrreqs = &mpls_usrreqs,
373 	},
374 };
375 
376 struct domain mplsdomain = {
377 	.dom_family = PF_MPLS,
378 	.dom_name = "MPLS",
379 	.dom_init = NULL,
380 	.dom_externalize = NULL,
381 	.dom_dispose = NULL,
382 	.dom_protosw = mplssw,
383 	.dom_protoswNPROTOSW = &mplssw[__arraycount(mplssw)],
384 	.dom_rtattach = rt_inithead,
385 	.dom_rtoffset = offsetof(struct sockaddr_mpls, smpls_addr) << 3,
386 	.dom_maxrtkey = sizeof(union mpls_shim),
387 	.dom_ifattach = NULL,
388 	.dom_ifdetach = NULL,
389 	.dom_ifqueues = { &mplsintrq, 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 };
395