xref: /minix3/minix/net/lwip/loopif.c (revision e4dbab1e5368dc2124168836ba46a7d3ff6414b0)
1 /* LWIP service - loopif.c - loopback interfaces */
2 /*
3  * There is always at least one loopback device.  This device is used also to
4  * loop back packets sent on other interfaces to the local interface address.
5  * Therefore, not all packets on the loopback device have a source or
6  * destination address corresponding to the loopback device.
7  */
8 
9 #include "lwip.h"
10 
11 /*
12  * As a safety measure, if lwIP somehow gets stuck in a loop replying to its
13  * own packets on a loopback interface, stop with immediately feeding packets
14  * back into lwIP after this many packets.  The remaining packets will still be
15  * delivered, but not before the main message loop has had a chance to run.
16  */
17 #define LOOPIF_LIMIT	65536
18 
19 /*
20  * The MTU is restricted to 65531 bytes, because we need space for a 4-byte
21  * header to identify the original interface of the packet.
22  */
23 #define LOOPIF_MAX_MTU	(UINT16_MAX - sizeof(uint32_t))	/* maximum MTU */
24 #define LOOPIF_DEF_MTU	LOOPIF_MAX_MTU			/* default MTU */
25 
26 #define NR_LOOPIF	2		/* number of loopback devices */
27 
28 struct loopif {
29 	struct ifdev loopif_ifdev;	/* interface device, MUST be first */
30 	struct pbuf *loopif_head;	/* head of pending loopback packets */
31 	struct pbuf **loopif_tailp;	/* tail ptr-ptr of pending packets */
32 	TAILQ_ENTRY(loopif) loopif_next;	/* next in free list */
33 } loopif_array[NR_LOOPIF];
34 
35 static TAILQ_HEAD(, loopif) loopif_freelist;	/* free loop interfaces list */
36 static TAILQ_HEAD(, loopif) loopif_activelist;	/* active loop interfaces */
37 
38 #define loopif_get_netif(loopif) (ifdev_get_netif(&(loopif)->loopif_ifdev))
39 
40 static unsigned int loopif_cksum_flags;
41 
42 static int loopif_create(const char *name);
43 
44 static const struct ifdev_ops loopif_ops;
45 
46 /*
47  * Initialize the loopback interface module.
48  */
49 void
50 loopif_init(void)
51 {
52 	unsigned int slot;
53 
54 	/* Initialize the lists of loopback interfaces. */
55 	TAILQ_INIT(&loopif_freelist);
56 	TAILQ_INIT(&loopif_activelist);
57 
58 	for (slot = 0; slot < __arraycount(loopif_array); slot++)
59 		TAILQ_INSERT_TAIL(&loopif_freelist, &loopif_array[slot],
60 		    loopif_next);
61 
62 	/*
63 	 * The default is to perform no checksumming on loopback interfaces,
64 	 * except for ICMP messages because otherwise we would need additional
65 	 * changes in the code receiving those.  In fact, for future
66 	 * compatibility, disable only those flags that we manage ourselves.
67 	 */
68 	loopif_cksum_flags = NETIF_CHECKSUM_ENABLE_ALL &
69 	    ~(NETIF_CHECKSUM_GEN_IP | NETIF_CHECKSUM_CHECK_IP |
70 	    NETIF_CHECKSUM_GEN_UDP | NETIF_CHECKSUM_CHECK_UDP |
71 	    NETIF_CHECKSUM_GEN_TCP | NETIF_CHECKSUM_CHECK_TCP);
72 
73 	/* Tell the ifdev module that users may create more loopif devices. */
74 	ifdev_register("lo", loopif_create);
75 }
76 
77 /*
78  * Polling function, invoked after each message loop iteration.  Forward any
79  * packets received on the output side of the loopback device during this
80  * loop iteration, to the input side of the device.
81  */
82 static void
83 loopif_poll(struct ifdev * ifdev)
84 {
85 	struct loopif *loopif = (struct loopif *)ifdev;
86 	struct pbuf *pbuf, **pnext;
87 	struct ifdev *oifdev;
88 	struct netif *netif;
89 	uint32_t oifindex;
90 	unsigned int count;
91 	static int warned = FALSE;
92 
93 	count = 0;
94 
95 	while ((pbuf = loopif->loopif_head) != NULL) {
96 		/*
97 		 * Prevent endless loops.  Keep in mind that packets may be
98 		 * added to the queue as part of processing packets from the
99 		 * queue here, so the queue itself will never reach this
100 		 * length.  As such the limit can (and must) be fairly high.
101 		 *
102 		 * In any case, if this warning is shown, that basically means
103 		 * that a bug in lwIP has been triggered.  There should be no
104 		 * such bugs, so if there are, they should be fixed in lwIP.
105 		 */
106 		if (count++ == LOOPIF_LIMIT) {
107 			if (!warned) {
108 				printf("LWIP: excess loopback traffic, "
109 				    "throttling output\n");
110 				warned = TRUE;
111 			}
112 
113 			break;
114 		}
115 
116 		pnext = pchain_end(pbuf);
117 
118 		if ((loopif->loopif_head = *pnext) == NULL)
119 			loopif->loopif_tailp = &loopif->loopif_head;
120 		*pnext = NULL;
121 
122 		/*
123 		 * Get the original interface for the packet, which if non-zero
124 		 * must also be used to pass the packet back to.  The interface
125 		 * should still exist in all cases, but better safe than sorry.
126 		 */
127 		memcpy(&oifindex, pbuf->payload, sizeof(oifindex));
128 
129 		util_pbuf_header(pbuf, -(int)sizeof(oifindex));
130 
131 		if (oifindex != 0 &&
132 		    (oifdev = ifdev_get_by_index(oifindex)) != NULL)
133 			netif = ifdev_get_netif(oifdev);
134 		else
135 			netif = NULL;
136 
137 		/*
138 		 * Loopback devices hand packets to BPF on output only.  Doing
139 		 * so on input as well would duplicate all captured packets.
140 		 */
141 		ifdev_input(ifdev, pbuf, netif, FALSE /*to_bpf*/);
142 	}
143 }
144 
145 /*
146  * Process a packet as output on a loopback interface.  Packets cannot be
147  * passed back into lwIP right away, nor can the original packets be passed
148  * back into lwIP.  Therefore, make a copy of the packet, and pass it back to
149  * lwIP at the end of the current message loop iteration.
150  */
151 static err_t
152 loopif_output(struct ifdev * ifdev, struct pbuf * pbuf, struct netif * netif)
153 {
154 	struct loopif *loopif = (struct loopif *)ifdev;
155 	struct ifdev *oifdev;
156 	struct pbuf *pcopy;
157 	uint32_t oifindex;
158 
159 	/* Reject oversized packets immediately.  This should not happen. */
160 	if (pbuf->tot_len > UINT16_MAX - sizeof(oifindex)) {
161 		printf("LWIP: attempt to send oversized loopback packet\n");
162 
163 		return ERR_MEM;
164 	}
165 
166 	/*
167 	 * If the service is low on memory, this is a likely place where
168 	 * allocation failures will occur.  Thus, do not print anything here.
169 	 * The user can diagnose such problems with interface statistics.
170 	 */
171 	pcopy = pchain_alloc(PBUF_RAW, sizeof(oifindex) + pbuf->tot_len);
172 	if (pcopy == NULL) {
173 		ifdev_output_drop(ifdev);
174 
175 		return ERR_MEM;
176 	}
177 
178 	/*
179 	 * If the packet was purposely diverted from a non-loopback interface
180 	 * to this interface, we have to remember the original interface, so
181 	 * that we can pass back the packet to that interface as well.  If we
182 	 * don't, packets to link-local addresses assigned to non-loopback
183 	 * interfaces will not be processed correctly.
184 	 */
185 	if (netif != NULL) {
186 		oifdev = netif_get_ifdev(netif);
187 		oifindex = ifdev_get_index(oifdev);
188 	} else
189 		oifindex = 0;
190 
191 	assert(pcopy->len >= sizeof(oifindex));
192 
193 	memcpy(pcopy->payload, &oifindex, sizeof(oifindex));
194 
195 	util_pbuf_header(pcopy, -(int)sizeof(oifindex));
196 
197 	if (pbuf_copy(pcopy, pbuf) != ERR_OK)
198 		panic("unexpected pbuf copy failure");
199 
200 	pcopy->flags |= pbuf->flags & (PBUF_FLAG_LLMCAST | PBUF_FLAG_LLBCAST);
201 
202 	util_pbuf_header(pcopy, sizeof(oifindex));
203 
204 	*loopif->loopif_tailp = pcopy;
205 	loopif->loopif_tailp = pchain_end(pcopy);
206 
207 	return ERR_OK;
208 }
209 
210 /*
211  * Initialization function for a loopback-type netif interface, called from
212  * lwIP at interface creation time.
213  */
214 static err_t
215 loopif_init_netif(struct ifdev * ifdev, struct netif * netif)
216 {
217 
218 	netif->name[0] = 'l';
219 	netif->name[1] = 'o';
220 
221 	/*
222 	 * FIXME: unfortunately, lwIP does not allow one to enable multicast on
223 	 * an interface without also enabling multicast management traffic
224 	 * (that is, IGMP and MLD).  Thus, for now, joining multicast groups
225 	 * and assigning local IPv6 addresses will incur such traffic even on
226 	 * loopback interfaces.  For now this is preferable over not supporting
227 	 * multicast on loopback interfaces at all.
228 	 */
229 	netif->flags |= NETIF_FLAG_IGMP | NETIF_FLAG_MLD6;
230 
231 	NETIF_SET_CHECKSUM_CTRL(netif, loopif_cksum_flags);
232 
233 	return ERR_OK;
234 }
235 
236 /*
237  * Create a new loopback device.
238  */
239 static int
240 loopif_create(const char * name)
241 {
242 	struct loopif *loopif;
243 
244 	/* Find a free loopback interface slot, if available. */
245 	if (TAILQ_EMPTY(&loopif_freelist))
246 		return ENOBUFS;
247 
248 	loopif = TAILQ_FIRST(&loopif_freelist);
249 	TAILQ_REMOVE(&loopif_freelist, loopif, loopif_next);
250 
251 	/* Initialize the loopif structure. */
252 	TAILQ_INSERT_HEAD(&loopif_activelist, loopif, loopif_next);
253 
254 	loopif->loopif_head = NULL;
255 	loopif->loopif_tailp = &loopif->loopif_head;
256 
257 	/*
258 	 * For simplicity and efficiency, we do not prepend the address family
259 	 * (IPv4/IPv6) to the packet for BPF, which means our loopback devices
260 	 * are of type DLT_RAW rather than (NetBSD's) DLT_NULL.
261 	 */
262 	ifdev_add(&loopif->loopif_ifdev, name, IFF_LOOPBACK | IFF_MULTICAST,
263 	    IFT_LOOP, 0 /*hdrlen*/, 0 /*addrlen*/, DLT_RAW, LOOPIF_MAX_MTU,
264 	    0 /*nd6flags*/, &loopif_ops);
265 
266 	ifdev_update_link(&loopif->loopif_ifdev, LINK_STATE_UP);
267 
268 	return OK;
269 }
270 
271 /*
272  * Destroy an existing loopback device.
273  */
274 static int
275 loopif_destroy(struct ifdev * ifdev)
276 {
277 	struct loopif *loopif = (struct loopif *)ifdev;
278 	struct pbuf *pbuf, **pnext;
279 	int r;
280 
281 	/*
282 	 * The ifdev module may refuse to remove this interface if it is the
283 	 * loopback interface used to loop back packets for other interfaces.
284 	 */
285 	if ((r = ifdev_remove(&loopif->loopif_ifdev)) != OK)
286 		return r;
287 
288 	/*
289 	 * Clean up.  The loopback queue can be non-empty only if we have been
290 	 * throttling in case of a feedback loop.
291 	 */
292 	while ((pbuf = loopif->loopif_head) != NULL) {
293 		pnext = pchain_end(pbuf);
294 
295 		if ((loopif->loopif_head = *pnext) == NULL)
296 			loopif->loopif_tailp = &loopif->loopif_head;
297 		*pnext = NULL;
298 
299 		pbuf_free(pbuf);
300 	}
301 
302 	TAILQ_REMOVE(&loopif_activelist, loopif, loopif_next);
303 
304 	TAILQ_INSERT_HEAD(&loopif_freelist, loopif, loopif_next);
305 
306 	return OK;
307 }
308 
309 /*
310  * Set NetBSD-style interface flags (IFF_) for a loopback interface.
311  */
312 static int
313 loopif_set_ifflags(struct ifdev * ifdev, unsigned int ifflags)
314 {
315 	struct loopif *loopif = (struct loopif *)ifdev;
316 
317 	/*
318 	 * Only the IFF_UP flag may be set and cleared.  We adjust the
319 	 * IFF_RUNNING flag immediately based on this flag.  This is a bit
320 	 * dangerous, but the caller takes this possibility into account.
321 	 */
322 	if ((ifflags & ~IFF_UP) != 0)
323 		return EINVAL;
324 
325 	if (ifflags & IFF_UP)
326 		ifdev_update_ifflags(&loopif->loopif_ifdev,
327 		    ifdev_get_ifflags(&loopif->loopif_ifdev) | IFF_RUNNING);
328 	else
329 		ifdev_update_ifflags(&loopif->loopif_ifdev,
330 		    ifdev_get_ifflags(&loopif->loopif_ifdev) & ~IFF_RUNNING);
331 
332 	return OK;
333 }
334 
335 /*
336  * Set the Maximum Transmission Unit for this interface.  Return TRUE if the
337  * new value is acceptable, in which case the caller will do the rest.  Return
338  * FALSE otherwise.
339  */
340 static int
341 loopif_set_mtu(struct ifdev * ifdev __unused, unsigned int mtu)
342 {
343 
344 	return (mtu <= LOOPIF_MAX_MTU);
345 }
346 
347 static const struct ifdev_ops loopif_ops = {
348 	.iop_init = loopif_init_netif,
349 	.iop_input = ip_input,
350 	.iop_output = loopif_output,
351 	.iop_poll = loopif_poll,
352 	.iop_set_ifflags = loopif_set_ifflags,
353 	.iop_set_mtu = loopif_set_mtu,
354 	.iop_destroy = loopif_destroy,
355 };
356 
357 /*
358  * Set and/or retrieve a per-protocol loopback checksumming option through
359  * sysctl(7).
360  */
361 ssize_t
362 loopif_cksum(struct rmib_call * call, struct rmib_node * node __unused,
363 	struct rmib_oldp * oldp, struct rmib_newp * newp)
364 {
365 	struct loopif *loopif;
366 	unsigned int flags;
367 	int r, val;
368 
369 	/*
370 	 * The third name field is the protocol.  We ignore the domain (the
371 	 * second field), thus sharing settings between PF_INET and PF_INET6.
372 	 * This is necessary because lwIP does not support TCP/UDP checksumming
373 	 * flags on a per-domain basis.
374 	 */
375 	switch (call->call_oname[2]) {
376 	case IPPROTO_IP:
377 		flags = NETIF_CHECKSUM_GEN_IP | NETIF_CHECKSUM_CHECK_IP;
378 		break;
379 	case IPPROTO_UDP:
380 		flags = NETIF_CHECKSUM_GEN_UDP | NETIF_CHECKSUM_CHECK_UDP;
381 		break;
382 	case IPPROTO_TCP:
383 		flags = NETIF_CHECKSUM_GEN_TCP | NETIF_CHECKSUM_CHECK_TCP;
384 		break;
385 	default:
386 		return EINVAL;
387 	}
388 
389 	/* Copy out the old (current) checksumming option. */
390 	if (oldp != NULL) {
391 		val = !!(loopif_cksum_flags & flags);
392 
393 		if ((r = rmib_copyout(oldp, 0, &val, sizeof(val))) < 0)
394 			return r;
395 	}
396 
397 	if (newp != NULL) {
398 		if ((r = rmib_copyin(newp, &val, sizeof(val))) != OK)
399 			return r;
400 
401 		if (val)
402 			loopif_cksum_flags |= flags;
403 		else
404 			loopif_cksum_flags &= ~flags;
405 
406 		/*
407 		 * Apply the new checksum flags to all loopback interfaces.
408 		 * Technically, this may result in dropped packets when
409 		 * enabling checksumming on a throttled loopif, but that is a
410 		 * case so rare and unimportant that we ignore it.
411 		 */
412 		TAILQ_FOREACH(loopif, &loopif_activelist, loopif_next) {
413 			NETIF_SET_CHECKSUM_CTRL(loopif_get_netif(loopif),
414 			    loopif_cksum_flags);
415 		}
416 	}
417 
418 	/* Return the length of the node. */
419 	return sizeof(val);
420 }
421