Line data Source code
1 : /* $OpenBSD: if_gre.c,v 1.124 2018/07/24 07:40:35 yasuoka Exp $ */
2 : /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */
3 :
4 : /*
5 : * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by Heiko W.Rupp <hwr@pilhuhn.de>
10 : *
11 : * IPv6-over-GRE contributed by Gert Doering <gert@greenie.muc.de>
12 : *
13 : * Redistribution and use in source and binary forms, with or without
14 : * modification, are permitted provided that the following conditions
15 : * are met:
16 : * 1. Redistributions of source code must retain the above copyright
17 : * notice, this list of conditions and the following disclaimer.
18 : * 2. Redistributions in binary form must reproduce the above copyright
19 : * notice, this list of conditions and the following disclaimer in the
20 : * documentation and/or other materials provided with the distribution.
21 : *
22 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 : * POSSIBILITY OF SUCH DAMAGE.
33 : */
34 :
35 : /*
36 : * Encapsulate L3 protocols into IP, per RFC 1701 and 1702.
37 : * See gre(4) for more details.
38 : * Also supported: IP in IP encapsulation (proto 55) per RFC 2004.
39 : */
40 :
41 : #include "bpfilter.h"
42 : #include "pf.h"
43 :
44 : #include <sys/param.h>
45 : #include <sys/mbuf.h>
46 : #include <sys/socket.h>
47 : #include <sys/sockio.h>
48 : #include <sys/kernel.h>
49 : #include <sys/systm.h>
50 : #include <sys/errno.h>
51 : #include <sys/timeout.h>
52 : #include <sys/queue.h>
53 : #include <sys/tree.h>
54 : #include <sys/pool.h>
55 : #include <sys/rwlock.h>
56 :
57 : #include <crypto/siphash.h>
58 :
59 : #include <net/if.h>
60 : #include <net/if_var.h>
61 : #include <net/if_types.h>
62 : #include <net/if_media.h>
63 : #include <net/route.h>
64 :
65 : #include <netinet/in.h>
66 : #include <netinet/in_var.h>
67 : #include <netinet/if_ether.h>
68 : #include <netinet/ip.h>
69 : #include <netinet/ip_var.h>
70 :
71 : #ifdef INET6
72 : #include <netinet/ip6.h>
73 : #include <netinet6/ip6_var.h>
74 : #include <netinet6/in6_var.h>
75 : #endif
76 :
77 : #ifdef PIPEX
78 : #include <net/pipex.h>
79 : #endif
80 :
81 : #ifdef MPLS
82 : #include <netmpls/mpls.h>
83 : #endif /* MPLS */
84 :
85 : #if NBPFILTER > 0
86 : #include <net/bpf.h>
87 : #endif
88 :
89 : #if NPF > 0
90 : #include <net/pfvar.h>
91 : #endif
92 :
93 : #include <net/if_gre.h>
94 :
95 : #include <netinet/ip_gre.h>
96 : #include <sys/sysctl.h>
97 :
98 : /* for nvgre bridge shizz */
99 : #include <sys/socket.h>
100 : #include <net/if_bridge.h>
101 :
102 : /*
103 : * packet formats
104 : */
105 : struct gre_header {
106 : uint16_t gre_flags;
107 : #define GRE_CP 0x8000 /* Checksum Present */
108 : #define GRE_KP 0x2000 /* Key Present */
109 : #define GRE_SP 0x1000 /* Sequence Present */
110 :
111 : #define GRE_VERS_MASK 0x0007
112 : #define GRE_VERS_0 0x0000
113 : #define GRE_VERS_1 0x0001
114 :
115 : uint16_t gre_proto;
116 : } __packed __aligned(4);
117 :
118 : struct gre_h_cksum {
119 : uint16_t gre_cksum;
120 : uint16_t gre_reserved1;
121 : } __packed __aligned(4);
122 :
123 : struct gre_h_key {
124 : uint32_t gre_key;
125 : } __packed __aligned(4);
126 :
127 : #define GRE_EOIP 0x6400
128 :
129 : struct gre_h_key_eoip {
130 : uint16_t eoip_len; /* network order */
131 : uint16_t eoip_tunnel_id; /* little endian */
132 : } __packed __aligned(4);
133 :
134 : #define NVGRE_VSID_RES_MIN 0x000000 /* reserved for future use */
135 : #define NVGRE_VSID_RES_MAX 0x000fff
136 : #define NVGRE_VSID_NVE2NVE 0xffffff /* vendor specific NVE-to-NVE comms */
137 :
138 : struct gre_h_seq {
139 : uint32_t gre_seq;
140 : } __packed __aligned(4);
141 :
142 : struct gre_h_wccp {
143 : uint8_t wccp_flags;
144 : uint8_t service_id;
145 : uint8_t alt_bucket;
146 : uint8_t pri_bucket;
147 : } __packed __aligned(4);
148 :
149 : #define GRE_WCCP 0x883e
150 :
151 : #define GRE_HDRLEN (sizeof(struct ip) + sizeof(struct gre_header))
152 :
153 : /*
154 : * GRE tunnel metadata
155 : */
156 :
157 : #define GRE_KA_NONE 0
158 : #define GRE_KA_DOWN 1
159 : #define GRE_KA_HOLD 2
160 : #define GRE_KA_UP 3
161 :
162 : union gre_addr {
163 : struct in_addr in4;
164 : struct in6_addr in6;
165 : };
166 :
167 : static inline int
168 : gre_ip_cmp(int, const union gre_addr *,
169 : const union gre_addr *);
170 :
171 : #define GRE_KEY_MIN 0x00000000U
172 : #define GRE_KEY_MAX 0xffffffffU
173 : #define GRE_KEY_SHIFT 0
174 :
175 : #define GRE_KEY_ENTROPY_MIN 0x00000000U
176 : #define GRE_KEY_ENTROPY_MAX 0x00ffffffU
177 : #define GRE_KEY_ENTROPY_SHIFT 8
178 :
179 : struct gre_tunnel {
180 : uint32_t t_key_mask;
181 : #define GRE_KEY_NONE htonl(0x00000000U)
182 : #define GRE_KEY_ENTROPY htonl(0xffffff00U)
183 : #define GRE_KEY_MASK htonl(0xffffffffU)
184 : uint32_t t_key;
185 :
186 : u_int t_rtableid;
187 : union gre_addr t_src;
188 : #define t_src4 t_src.in4
189 : #define t_src6 t_src.in6
190 : union gre_addr t_dst;
191 : #define t_dst4 t_dst.in4
192 : #define t_dst6 t_dst.in6
193 : int t_ttl;
194 : uint16_t t_df;
195 : sa_family_t t_af;
196 : };
197 :
198 : static int
199 : gre_cmp_src(const struct gre_tunnel *,
200 : const struct gre_tunnel *);
201 : static int
202 : gre_cmp(const struct gre_tunnel *, const struct gre_tunnel *);
203 :
204 : static int gre_set_tunnel(struct gre_tunnel *, struct if_laddrreq *, int);
205 : static int gre_get_tunnel(struct gre_tunnel *, struct if_laddrreq *);
206 : static int gre_del_tunnel(struct gre_tunnel *);
207 :
208 : static int gre_set_vnetid(struct gre_tunnel *, struct ifreq *);
209 : static int gre_get_vnetid(struct gre_tunnel *, struct ifreq *);
210 : static int gre_del_vnetid(struct gre_tunnel *);
211 :
212 : static int gre_set_vnetflowid(struct gre_tunnel *, struct ifreq *);
213 : static int gre_get_vnetflowid(struct gre_tunnel *, struct ifreq *);
214 :
215 : static struct mbuf *
216 : gre_encap_dst(const struct gre_tunnel *, const union gre_addr *,
217 : struct mbuf *, uint16_t, uint8_t, uint8_t);
218 : #define gre_encap(_t, _m, _p, _ttl, _tos) \
219 : gre_encap_dst((_t), &(_t)->t_dst, (_m), (_p), (_ttl), (_tos))
220 :
221 : static struct mbuf *
222 : gre_encap_dst_ip(const struct gre_tunnel *,
223 : const union gre_addr *, struct mbuf *, uint8_t, uint8_t);
224 : #define gre_encap_ip(_t, _m, _ttl, _tos) \
225 : gre_encap_dst_ip((_t), &(_t)->t_dst, (_m), (_ttl), (_tos))
226 :
227 : static int
228 : gre_ip_output(const struct gre_tunnel *, struct mbuf *);
229 :
230 : static int gre_tunnel_ioctl(struct ifnet *, struct gre_tunnel *,
231 : u_long, void *);
232 :
233 : /*
234 : * layer 3 GRE tunnels
235 : */
236 :
237 : struct gre_softc {
238 : struct gre_tunnel sc_tunnel; /* must be first */
239 : TAILQ_ENTRY(gre_softc) sc_entry;
240 :
241 : struct ifnet sc_if;
242 :
243 : struct timeout sc_ka_send;
244 : struct timeout sc_ka_hold;
245 :
246 : unsigned int sc_ka_state;
247 : unsigned int sc_ka_timeo;
248 : unsigned int sc_ka_count;
249 :
250 : unsigned int sc_ka_holdmax;
251 : unsigned int sc_ka_holdcnt;
252 :
253 : SIPHASH_KEY sc_ka_key;
254 : uint32_t sc_ka_bias;
255 : int sc_ka_recvtm;
256 : };
257 :
258 : TAILQ_HEAD(gre_list, gre_softc);
259 :
260 : struct gre_keepalive {
261 : uint32_t gk_uptime;
262 : uint32_t gk_random;
263 : uint8_t gk_digest[SIPHASH_DIGEST_LENGTH];
264 : } __packed __aligned(4);
265 :
266 : static int gre_clone_create(struct if_clone *, int);
267 : static int gre_clone_destroy(struct ifnet *);
268 :
269 : struct if_clone gre_cloner =
270 : IF_CLONE_INITIALIZER("gre", gre_clone_create, gre_clone_destroy);
271 :
272 : /* protected by NET_LOCK */
273 : struct gre_list gre_list = TAILQ_HEAD_INITIALIZER(gre_list);
274 :
275 : static int gre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
276 : struct rtentry *);
277 : static void gre_start(struct ifnet *);
278 : static int gre_ioctl(struct ifnet *, u_long, caddr_t);
279 :
280 : static int gre_up(struct gre_softc *);
281 : static int gre_down(struct gre_softc *);
282 : static void gre_link_state(struct ifnet *, unsigned int);
283 :
284 : static int gre_input_key(struct mbuf **, int *, int, int,
285 : struct gre_tunnel *);
286 :
287 : static void gre_keepalive_send(void *);
288 : static void gre_keepalive_recv(struct ifnet *ifp, struct mbuf *);
289 : static void gre_keepalive_hold(void *);
290 :
291 : static struct mbuf *
292 : gre_l3_encap_dst(const struct gre_tunnel *, const void *,
293 : struct mbuf *m, sa_family_t);
294 :
295 : #define gre_l3_encap(_t, _m, _af) \
296 : gre_l3_encap_dst((_t), &(_t)->t_dst, (_m), (_af))
297 :
298 : struct mgre_softc {
299 : struct gre_tunnel sc_tunnel; /* must be first */
300 : RBT_ENTRY(mgre_softc) sc_entry;
301 :
302 : struct ifnet sc_if;
303 : };
304 :
305 : RBT_HEAD(mgre_tree, mgre_softc);
306 :
307 : static inline int
308 : mgre_cmp(const struct mgre_softc *, const struct mgre_softc *);
309 :
310 0 : RBT_PROTOTYPE(mgre_tree, mgre_softc, sc_entry, mgre_cmp);
311 :
312 : static int mgre_clone_create(struct if_clone *, int);
313 : static int mgre_clone_destroy(struct ifnet *);
314 :
315 : struct if_clone mgre_cloner =
316 : IF_CLONE_INITIALIZER("mgre", mgre_clone_create, mgre_clone_destroy);
317 :
318 : static void mgre_rtrequest(struct ifnet *, int, struct rtentry *);
319 : static int mgre_output(struct ifnet *, struct mbuf *, struct sockaddr *,
320 : struct rtentry *);
321 : static void mgre_start(struct ifnet *);
322 : static int mgre_ioctl(struct ifnet *, u_long, caddr_t);
323 :
324 : static int mgre_set_tunnel(struct mgre_softc *, struct if_laddrreq *);
325 : static int mgre_get_tunnel(struct mgre_softc *, struct if_laddrreq *);
326 : static int mgre_up(struct mgre_softc *);
327 : static int mgre_down(struct mgre_softc *);
328 :
329 : /* protected by NET_LOCK */
330 : struct mgre_tree mgre_tree = RBT_INITIALIZER();
331 :
332 : /*
333 : * Ethernet GRE tunnels
334 : */
335 : #define ether_cmp(_a, _b) memcmp((_a), (_b), ETHER_ADDR_LEN)
336 : #define ether_isequal(_a, _b) (ether_cmp((_a), (_b)) == 0)
337 : #define ether_isbcast(_e) ether_isequal((_e), etherbroadcastaddr)
338 :
339 : static struct mbuf *
340 : gre_ether_align(struct mbuf *, int);
341 :
342 : struct egre_softc {
343 : struct gre_tunnel sc_tunnel; /* must be first */
344 : RBT_ENTRY(egre_softc) sc_entry;
345 :
346 : struct arpcom sc_ac;
347 : struct ifmedia sc_media;
348 : };
349 :
350 : RBT_HEAD(egre_tree, egre_softc);
351 :
352 : static inline int
353 : egre_cmp(const struct egre_softc *, const struct egre_softc *);
354 :
355 0 : RBT_PROTOTYPE(egre_tree, egre_softc, sc_entry, egre_cmp);
356 :
357 : static int egre_clone_create(struct if_clone *, int);
358 : static int egre_clone_destroy(struct ifnet *);
359 :
360 : static void egre_start(struct ifnet *);
361 : static int egre_ioctl(struct ifnet *, u_long, caddr_t);
362 : static int egre_media_change(struct ifnet *);
363 : static void egre_media_status(struct ifnet *, struct ifmediareq *);
364 :
365 : static int egre_up(struct egre_softc *);
366 : static int egre_down(struct egre_softc *);
367 :
368 : static int egre_input(const struct gre_tunnel *, struct mbuf *, int);
369 : struct if_clone egre_cloner =
370 : IF_CLONE_INITIALIZER("egre", egre_clone_create, egre_clone_destroy);
371 :
372 : /* protected by NET_LOCK */
373 : struct egre_tree egre_tree = RBT_INITIALIZER();
374 :
375 : /*
376 : * Network Virtualisation Using Generic Routing Encapsulation (NVGRE)
377 : */
378 :
379 : #define NVGRE_AGE_TMO 100 /* seconds */
380 :
381 : struct nvgre_entry {
382 : RB_ENTRY(nvgre_entry) nv_entry;
383 : struct ether_addr nv_dst;
384 : uint8_t nv_type;
385 : #define NVGRE_ENTRY_DYNAMIC 0
386 : #define NVGRE_ENTRY_STATIC 1
387 : union gre_addr nv_gateway;
388 : struct refcnt nv_refs;
389 : int nv_age;
390 : };
391 :
392 : RBT_HEAD(nvgre_map, nvgre_entry);
393 :
394 : static inline int
395 : nvgre_entry_cmp(const struct nvgre_entry *,
396 : const struct nvgre_entry *);
397 :
398 0 : RBT_PROTOTYPE(nvgre_map, nvgre_entry, nv_entry, nvgre_entry_cmp);
399 :
400 : struct nvgre_softc {
401 : struct gre_tunnel sc_tunnel; /* must be first */
402 : unsigned int sc_ifp0;
403 : RBT_ENTRY(nvgre_softc) sc_uentry;
404 : RBT_ENTRY(nvgre_softc) sc_mentry;
405 :
406 : struct arpcom sc_ac;
407 : struct ifmedia sc_media;
408 :
409 : struct mbuf_queue sc_send_list;
410 : struct task sc_send_task;
411 :
412 : void *sc_inm;
413 : void *sc_lhcookie;
414 : void *sc_dhcookie;
415 :
416 : struct rwlock sc_ether_lock;
417 : struct nvgre_map sc_ether_map;
418 : unsigned int sc_ether_num;
419 : unsigned int sc_ether_max;
420 : int sc_ether_tmo;
421 : struct timeout sc_ether_age;
422 : };
423 :
424 : RBT_HEAD(nvgre_ucast_tree, nvgre_softc);
425 : RBT_HEAD(nvgre_mcast_tree, nvgre_softc);
426 :
427 : static inline int
428 : nvgre_cmp_ucast(const struct nvgre_softc *,
429 : const struct nvgre_softc *);
430 : static int
431 : nvgre_cmp_mcast(const struct gre_tunnel *,
432 : const union gre_addr *, unsigned int,
433 : const struct gre_tunnel *, const union gre_addr *,
434 : unsigned int);
435 : static inline int
436 : nvgre_cmp_mcast_sc(const struct nvgre_softc *,
437 : const struct nvgre_softc *);
438 :
439 0 : RBT_PROTOTYPE(nvgre_ucast_tree, nvgre_softc, sc_uentry, nvgre_cmp_ucast);
440 0 : RBT_PROTOTYPE(nvgre_mcast_tree, nvgre_softc, sc_mentry, nvgre_cmp_mcast_sc);
441 :
442 : static int nvgre_clone_create(struct if_clone *, int);
443 : static int nvgre_clone_destroy(struct ifnet *);
444 :
445 : static void nvgre_start(struct ifnet *);
446 : static int nvgre_ioctl(struct ifnet *, u_long, caddr_t);
447 :
448 : static int nvgre_up(struct nvgre_softc *);
449 : static int nvgre_down(struct nvgre_softc *);
450 : static int nvgre_set_parent(struct nvgre_softc *, const char *);
451 : static void nvgre_link_change(void *);
452 : static void nvgre_detach(void *);
453 :
454 : static int nvgre_input(const struct gre_tunnel *, struct mbuf *, int);
455 : static void nvgre_send(void *);
456 :
457 : static int nvgre_rtfind(struct nvgre_softc *, struct ifbaconf *);
458 : static void nvgre_flush_map(struct nvgre_softc *);
459 : static void nvgre_input_map(struct nvgre_softc *,
460 : const struct gre_tunnel *, const struct ether_header *);
461 : static void nvgre_age(void *);
462 :
463 : struct if_clone nvgre_cloner =
464 : IF_CLONE_INITIALIZER("nvgre", nvgre_clone_create, nvgre_clone_destroy);
465 :
466 : struct pool nvgre_pool;
467 :
468 : /* protected by NET_LOCK */
469 : struct nvgre_ucast_tree nvgre_ucast_tree = RBT_INITIALIZER();
470 : struct nvgre_mcast_tree nvgre_mcast_tree = RBT_INITIALIZER();
471 :
472 : /*
473 : * MikroTik Ethernet over IP protocol (eoip)
474 : */
475 :
476 : struct eoip_softc {
477 : struct gre_tunnel sc_tunnel; /* must be first */
478 : uint16_t sc_tunnel_id;
479 : RBT_ENTRY(eoip_softc) sc_entry;
480 :
481 : struct arpcom sc_ac;
482 : struct ifmedia sc_media;
483 :
484 : struct timeout sc_ka_send;
485 : struct timeout sc_ka_hold;
486 :
487 : unsigned int sc_ka_state;
488 : unsigned int sc_ka_timeo;
489 : unsigned int sc_ka_count;
490 :
491 : unsigned int sc_ka_holdmax;
492 : unsigned int sc_ka_holdcnt;
493 : };
494 :
495 : RBT_HEAD(eoip_tree, eoip_softc);
496 :
497 : static inline int
498 : eoip_cmp(const struct eoip_softc *, const struct eoip_softc *);
499 :
500 0 : RBT_PROTOTYPE(eoip_tree, eoip_softc, sc_entry, eoip_cmp);
501 :
502 : static int eoip_clone_create(struct if_clone *, int);
503 : static int eoip_clone_destroy(struct ifnet *);
504 :
505 : static void eoip_start(struct ifnet *);
506 : static int eoip_ioctl(struct ifnet *, u_long, caddr_t);
507 :
508 : static void eoip_keepalive_send(void *);
509 : static void eoip_keepalive_recv(struct eoip_softc *);
510 : static void eoip_keepalive_hold(void *);
511 :
512 : static int eoip_up(struct eoip_softc *);
513 : static int eoip_down(struct eoip_softc *);
514 :
515 : static struct mbuf *
516 : eoip_encap(struct eoip_softc *, struct mbuf *, uint8_t);
517 :
518 : static struct mbuf *
519 : eoip_input(struct gre_tunnel *, struct mbuf *,
520 : const struct gre_header *, int);
521 : struct if_clone eoip_cloner =
522 : IF_CLONE_INITIALIZER("eoip", eoip_clone_create, eoip_clone_destroy);
523 :
524 : /* protected by NET_LOCK */
525 : struct eoip_tree eoip_tree = RBT_INITIALIZER();
526 :
527 : /*
528 : * It is not easy to calculate the right value for a GRE MTU.
529 : * We leave this task to the admin and use the same default that
530 : * other vendors use.
531 : */
532 : #define GREMTU 1476
533 :
534 : /*
535 : * We can control the acceptance of GRE and MobileIP packets by
536 : * altering the sysctl net.inet.gre.allow values
537 : * respectively. Zero means drop them, all else is acceptance. We can also
538 : * control acceptance of WCCPv1-style GRE packets through the
539 : * net.inet.gre.wccp value, but be aware it depends upon normal GRE being
540 : * allowed as well.
541 : *
542 : */
543 : int gre_allow = 0;
544 : int gre_wccp = 0;
545 :
546 : void
547 0 : greattach(int n)
548 : {
549 0 : if_clone_attach(&gre_cloner);
550 0 : if_clone_attach(&mgre_cloner);
551 0 : if_clone_attach(&egre_cloner);
552 0 : if_clone_attach(&nvgre_cloner);
553 0 : if_clone_attach(&eoip_cloner);
554 0 : }
555 :
556 : static int
557 0 : gre_clone_create(struct if_clone *ifc, int unit)
558 : {
559 : struct gre_softc *sc;
560 : struct ifnet *ifp;
561 :
562 0 : sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
563 0 : snprintf(sc->sc_if.if_xname, sizeof sc->sc_if.if_xname, "%s%d",
564 0 : ifc->ifc_name, unit);
565 :
566 : ifp = &sc->sc_if;
567 0 : ifp->if_softc = sc;
568 0 : ifp->if_type = IFT_TUNNEL;
569 0 : ifp->if_hdrlen = GRE_HDRLEN;
570 0 : ifp->if_mtu = GREMTU;
571 0 : ifp->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
572 0 : ifp->if_xflags = IFXF_CLONED;
573 0 : ifp->if_output = gre_output;
574 0 : ifp->if_start = gre_start;
575 0 : ifp->if_ioctl = gre_ioctl;
576 0 : ifp->if_rtrequest = p2p_rtrequest;
577 :
578 0 : sc->sc_tunnel.t_ttl = ip_defttl;
579 0 : sc->sc_tunnel.t_df = htons(0);
580 :
581 0 : timeout_set(&sc->sc_ka_send, gre_keepalive_send, sc);
582 0 : timeout_set_proc(&sc->sc_ka_hold, gre_keepalive_hold, sc);
583 0 : sc->sc_ka_state = GRE_KA_NONE;
584 :
585 0 : if_attach(ifp);
586 0 : if_alloc_sadl(ifp);
587 :
588 : #if NBPFILTER > 0
589 0 : bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t));
590 : #endif
591 :
592 0 : NET_LOCK();
593 0 : TAILQ_INSERT_TAIL(&gre_list, sc, sc_entry);
594 0 : NET_UNLOCK();
595 :
596 0 : return (0);
597 : }
598 :
599 : static int
600 0 : gre_clone_destroy(struct ifnet *ifp)
601 : {
602 0 : struct gre_softc *sc = ifp->if_softc;
603 :
604 0 : NET_LOCK();
605 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
606 0 : gre_down(sc);
607 :
608 0 : TAILQ_REMOVE(&gre_list, sc, sc_entry);
609 0 : NET_UNLOCK();
610 :
611 0 : if_detach(ifp);
612 :
613 0 : free(sc, M_DEVBUF, sizeof(*sc));
614 :
615 0 : return (0);
616 : }
617 :
618 : static int
619 0 : mgre_clone_create(struct if_clone *ifc, int unit)
620 : {
621 : struct mgre_softc *sc;
622 : struct ifnet *ifp;
623 :
624 0 : sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
625 0 : ifp = &sc->sc_if;
626 :
627 0 : snprintf(ifp->if_xname, sizeof(ifp->if_xname),
628 0 : "%s%d", ifc->ifc_name, unit);
629 :
630 0 : ifp->if_softc = sc;
631 0 : ifp->if_type = IFT_L3IPVLAN;
632 0 : ifp->if_hdrlen = GRE_HDRLEN;
633 0 : ifp->if_mtu = GREMTU;
634 0 : ifp->if_flags = IFF_MULTICAST|IFF_SIMPLEX;
635 0 : ifp->if_xflags = IFXF_CLONED;
636 0 : ifp->if_rtrequest = mgre_rtrequest;
637 0 : ifp->if_output = mgre_output;
638 0 : ifp->if_start = mgre_start;
639 0 : ifp->if_ioctl = mgre_ioctl;
640 :
641 0 : sc->sc_tunnel.t_ttl = ip_defttl;
642 0 : sc->sc_tunnel.t_df = htons(0);
643 :
644 0 : if_attach(ifp);
645 0 : if_alloc_sadl(ifp);
646 :
647 : #if NBPFILTER > 0
648 0 : bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(uint32_t));
649 : #endif
650 :
651 0 : return (0);
652 : }
653 :
654 : static int
655 0 : mgre_clone_destroy(struct ifnet *ifp)
656 : {
657 0 : struct mgre_softc *sc = ifp->if_softc;
658 :
659 0 : NET_LOCK();
660 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
661 0 : mgre_down(sc);
662 0 : NET_UNLOCK();
663 :
664 0 : if_detach(ifp);
665 :
666 0 : free(sc, M_DEVBUF, sizeof(*sc));
667 :
668 0 : return (0);
669 : }
670 :
671 : static int
672 0 : egre_clone_create(struct if_clone *ifc, int unit)
673 : {
674 : struct egre_softc *sc;
675 : struct ifnet *ifp;
676 :
677 0 : sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
678 0 : ifp = &sc->sc_ac.ac_if;
679 :
680 0 : snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d",
681 0 : ifc->ifc_name, unit);
682 :
683 0 : ifp->if_softc = sc;
684 0 : ifp->if_mtu = 1500; /* XXX */
685 0 : ifp->if_ioctl = egre_ioctl;
686 0 : ifp->if_start = egre_start;
687 0 : ifp->if_xflags = IFXF_CLONED;
688 0 : IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
689 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
690 0 : ether_fakeaddr(ifp);
691 :
692 0 : sc->sc_tunnel.t_ttl = ip_defttl;
693 0 : sc->sc_tunnel.t_df = htons(0);
694 :
695 0 : ifmedia_init(&sc->sc_media, 0, egre_media_change, egre_media_status);
696 0 : ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
697 0 : ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
698 :
699 0 : if_attach(ifp);
700 0 : ether_ifattach(ifp);
701 :
702 0 : return (0);
703 : }
704 :
705 : static int
706 0 : egre_clone_destroy(struct ifnet *ifp)
707 : {
708 0 : struct egre_softc *sc = ifp->if_softc;
709 :
710 0 : NET_LOCK();
711 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
712 0 : egre_down(sc);
713 0 : NET_UNLOCK();
714 :
715 0 : ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
716 0 : ether_ifdetach(ifp);
717 0 : if_detach(ifp);
718 :
719 0 : free(sc, M_DEVBUF, sizeof(*sc));
720 :
721 0 : return (0);
722 : }
723 :
724 : static int
725 0 : nvgre_clone_create(struct if_clone *ifc, int unit)
726 : {
727 : struct nvgre_softc *sc;
728 : struct ifnet *ifp;
729 : struct gre_tunnel *tunnel;
730 :
731 0 : if (nvgre_pool.pr_size == 0) {
732 0 : pool_init(&nvgre_pool, sizeof(struct nvgre_entry), 0,
733 : IPL_SOFTNET, 0, "nvgren", NULL);
734 0 : }
735 :
736 0 : sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
737 0 : ifp = &sc->sc_ac.ac_if;
738 :
739 0 : snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d",
740 0 : ifc->ifc_name, unit);
741 :
742 0 : ifp->if_softc = sc;
743 0 : ifp->if_mtu = 1500; /* XXX */
744 0 : ifp->if_ioctl = nvgre_ioctl;
745 0 : ifp->if_start = nvgre_start;
746 0 : ifp->if_xflags = IFXF_CLONED;
747 0 : IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
748 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
749 0 : ether_fakeaddr(ifp);
750 :
751 0 : tunnel = &sc->sc_tunnel;
752 0 : tunnel->t_ttl = IP_DEFAULT_MULTICAST_TTL;
753 0 : tunnel->t_df = htons(IP_DF);
754 0 : tunnel->t_key_mask = GRE_KEY_ENTROPY;
755 0 : tunnel->t_key = htonl((NVGRE_VSID_RES_MAX + 1) <<
756 : GRE_KEY_ENTROPY_SHIFT);
757 :
758 0 : mq_init(&sc->sc_send_list, IFQ_MAXLEN * 2, IPL_SOFTNET);
759 0 : task_set(&sc->sc_send_task, nvgre_send, sc);
760 :
761 0 : rw_init(&sc->sc_ether_lock, "nvgrelk");
762 0 : RBT_INIT(nvgre_map, &sc->sc_ether_map);
763 0 : sc->sc_ether_num = 0;
764 0 : sc->sc_ether_max = 100;
765 0 : sc->sc_ether_tmo = 240 * hz;
766 0 : timeout_set_proc(&sc->sc_ether_age, nvgre_age, sc); /* ugh */
767 :
768 0 : ifmedia_init(&sc->sc_media, 0, egre_media_change, egre_media_status);
769 0 : ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
770 0 : ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
771 :
772 0 : if_attach(ifp);
773 0 : ether_ifattach(ifp);
774 :
775 0 : return (0);
776 : }
777 :
778 : static int
779 0 : nvgre_clone_destroy(struct ifnet *ifp)
780 : {
781 0 : struct nvgre_softc *sc = ifp->if_softc;
782 :
783 0 : NET_LOCK();
784 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
785 0 : nvgre_down(sc);
786 0 : NET_UNLOCK();
787 :
788 0 : ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
789 0 : ether_ifdetach(ifp);
790 0 : if_detach(ifp);
791 :
792 0 : free(sc, M_DEVBUF, sizeof(*sc));
793 :
794 0 : return (0);
795 : }
796 :
797 : static int
798 0 : eoip_clone_create(struct if_clone *ifc, int unit)
799 : {
800 : struct eoip_softc *sc;
801 : struct ifnet *ifp;
802 :
803 0 : sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO);
804 0 : ifp = &sc->sc_ac.ac_if;
805 :
806 0 : snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d",
807 0 : ifc->ifc_name, unit);
808 :
809 0 : ifp->if_softc = sc;
810 0 : ifp->if_ioctl = eoip_ioctl;
811 0 : ifp->if_start = eoip_start;
812 0 : ifp->if_xflags = IFXF_CLONED;
813 0 : IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
814 0 : ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
815 0 : ether_fakeaddr(ifp);
816 :
817 0 : sc->sc_tunnel.t_ttl = ip_defttl;
818 0 : sc->sc_tunnel.t_df = htons(0);
819 :
820 0 : sc->sc_ka_timeo = 10;
821 0 : sc->sc_ka_count = 10;
822 :
823 0 : timeout_set(&sc->sc_ka_send, eoip_keepalive_send, sc);
824 0 : timeout_set_proc(&sc->sc_ka_hold, eoip_keepalive_hold, sc);
825 0 : sc->sc_ka_state = GRE_KA_DOWN;
826 :
827 0 : ifmedia_init(&sc->sc_media, 0, egre_media_change, egre_media_status);
828 0 : ifmedia_add(&sc->sc_media, IFM_ETHER | IFM_AUTO, 0, NULL);
829 0 : ifmedia_set(&sc->sc_media, IFM_ETHER | IFM_AUTO);
830 :
831 0 : if_attach(ifp);
832 0 : ether_ifattach(ifp);
833 :
834 0 : return (0);
835 : }
836 :
837 : static int
838 0 : eoip_clone_destroy(struct ifnet *ifp)
839 : {
840 0 : struct eoip_softc *sc = ifp->if_softc;
841 :
842 0 : NET_LOCK();
843 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
844 0 : eoip_down(sc);
845 0 : NET_UNLOCK();
846 :
847 0 : ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
848 0 : ether_ifdetach(ifp);
849 0 : if_detach(ifp);
850 :
851 0 : free(sc, M_DEVBUF, sizeof(*sc));
852 :
853 0 : return (0);
854 : }
855 :
856 : int
857 0 : gre_input(struct mbuf **mp, int *offp, int type, int af)
858 : {
859 0 : struct mbuf *m = *mp;
860 0 : struct gre_tunnel key;
861 : struct ip *ip;
862 :
863 0 : ip = mtod(m, struct ip *);
864 :
865 : /* XXX check if ip_src is sane for nvgre? */
866 :
867 0 : key.t_af = AF_INET;
868 0 : key.t_ttl = ip->ip_ttl;
869 0 : key.t_src4 = ip->ip_dst;
870 0 : key.t_dst4 = ip->ip_src;
871 :
872 0 : if (gre_input_key(mp, offp, type, af, &key) == -1)
873 0 : return (rip_input(mp, offp, type, af));
874 :
875 0 : return (IPPROTO_DONE);
876 0 : }
877 :
878 : #ifdef INET6
879 : int
880 0 : gre_input6(struct mbuf **mp, int *offp, int type, int af)
881 : {
882 0 : struct mbuf *m = *mp;
883 0 : struct gre_tunnel key;
884 : struct ip6_hdr *ip6;
885 :
886 0 : ip6 = mtod(m, struct ip6_hdr *);
887 :
888 : /* XXX check if ip6_src is sane for nvgre? */
889 :
890 0 : key.t_af = AF_INET6;
891 0 : key.t_ttl = ip6->ip6_hlim;
892 0 : key.t_src6 = ip6->ip6_dst;
893 0 : key.t_dst6 = ip6->ip6_src;
894 :
895 0 : if (gre_input_key(mp, offp, type, af, &key) == -1)
896 0 : return (rip6_input(mp, offp, type, af));
897 :
898 0 : return (IPPROTO_DONE);
899 0 : }
900 : #endif /* INET6 */
901 :
902 : static inline struct ifnet *
903 0 : gre_find(const struct gre_tunnel *key)
904 : {
905 : struct gre_softc *sc;
906 :
907 0 : TAILQ_FOREACH(sc, &gre_list, sc_entry) {
908 0 : if (gre_cmp(key, &sc->sc_tunnel) != 0)
909 : continue;
910 :
911 0 : if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING))
912 : continue;
913 :
914 0 : return (&sc->sc_if);
915 : }
916 :
917 0 : return (NULL);
918 0 : }
919 :
920 : static inline struct ifnet *
921 0 : mgre_find(const struct gre_tunnel *key)
922 : {
923 : struct mgre_softc *sc;
924 :
925 0 : NET_ASSERT_LOCKED();
926 0 : sc = RBT_FIND(mgre_tree, &mgre_tree, (const struct mgre_softc *)key);
927 0 : if (sc != NULL)
928 0 : return (&sc->sc_if);
929 :
930 0 : return (NULL);
931 0 : }
932 :
933 : static struct mbuf *
934 0 : gre_input_1(struct gre_tunnel *key, struct mbuf *m,
935 : const struct gre_header *gh, int iphlen)
936 : {
937 0 : switch (gh->gre_proto) {
938 : case htons(ETHERTYPE_PPP):
939 : #ifdef PIPEX
940 0 : if (pipex_enable) {
941 : struct pipex_session *session;
942 :
943 0 : session = pipex_pptp_lookup_session(m);
944 0 : if (session != NULL &&
945 0 : pipex_pptp_input(m, session) == NULL)
946 0 : return (NULL);
947 0 : }
948 : #endif
949 : break;
950 : case htons(GRE_EOIP):
951 0 : return (eoip_input(key, m, gh, iphlen));
952 : break;
953 : }
954 :
955 0 : return (m);
956 0 : }
957 :
958 : static int
959 0 : gre_input_key(struct mbuf **mp, int *offp, int type, int af,
960 : struct gre_tunnel *key)
961 : {
962 0 : struct mbuf *m = *mp;
963 0 : int iphlen = *offp, hlen;
964 : struct ifnet *ifp;
965 : const struct gre_tunnel *tunnel;
966 : caddr_t buf;
967 : struct gre_header *gh;
968 : struct gre_h_key *gkh;
969 : void (*input)(struct ifnet *, struct mbuf *);
970 : int bpf_af = AF_UNSPEC; /* bpf */
971 : int mcast = 0;
972 : int ttloff;
973 :
974 0 : if (!gre_allow)
975 : goto decline;
976 :
977 0 : key->t_rtableid = m->m_pkthdr.ph_rtableid;
978 :
979 0 : hlen = iphlen + sizeof(*gh);
980 0 : if (m->m_pkthdr.len < hlen)
981 : goto decline;
982 :
983 0 : m = m_pullup(m, hlen);
984 0 : if (m == NULL)
985 0 : return (IPPROTO_DONE);
986 :
987 0 : buf = mtod(m, caddr_t);
988 0 : gh = (struct gre_header *)(buf + iphlen);
989 :
990 : /* check the version */
991 0 : switch (gh->gre_flags & htons(GRE_VERS_MASK)) {
992 : case htons(GRE_VERS_0):
993 : break;
994 :
995 : case htons(GRE_VERS_1):
996 0 : m = gre_input_1(key, m, gh, iphlen);
997 0 : if (m == NULL)
998 0 : return (IPPROTO_DONE);
999 : /* FALLTHROUGH */
1000 : default:
1001 : goto decline;
1002 : }
1003 :
1004 : /* the only optional bit in the header is K flag */
1005 0 : if ((gh->gre_flags & htons(~(GRE_KP|GRE_VERS_MASK))) != htons(0))
1006 : goto decline;
1007 :
1008 0 : if (gh->gre_flags & htons(GRE_KP)) {
1009 0 : hlen += sizeof(*gkh);
1010 0 : if (m->m_pkthdr.len < hlen)
1011 : goto decline;
1012 :
1013 0 : m = m_pullup(m, hlen);
1014 0 : if (m == NULL)
1015 0 : return (IPPROTO_DONE);
1016 :
1017 0 : buf = mtod(m, caddr_t);
1018 0 : gh = (struct gre_header *)(buf + iphlen);
1019 0 : gkh = (struct gre_h_key *)(gh + 1);
1020 :
1021 0 : key->t_key_mask = GRE_KEY_MASK;
1022 0 : key->t_key = gkh->gre_key;
1023 0 : } else
1024 0 : key->t_key_mask = GRE_KEY_NONE;
1025 :
1026 0 : if (gh->gre_proto == htons(ETHERTYPE_TRANSETHER)) {
1027 0 : if (egre_input(key, m, hlen) == -1 &&
1028 0 : nvgre_input(key, m, hlen) == -1)
1029 : goto decline;
1030 :
1031 0 : return (IPPROTO_DONE);
1032 : }
1033 :
1034 0 : ifp = gre_find(key);
1035 0 : if (ifp == NULL) {
1036 0 : ifp = mgre_find(key);
1037 0 : if (ifp == NULL)
1038 : goto decline;
1039 : }
1040 :
1041 0 : switch (gh->gre_proto) {
1042 : case htons(GRE_WCCP): {
1043 : struct mbuf *n;
1044 0 : int off;
1045 :
1046 : /* WCCP/GRE:
1047 : * So far as I can see (and test) it seems that Cisco's WCCP
1048 : * GRE tunnel is precisely a IP-in-GRE tunnel that differs
1049 : * only in its protocol number. At least, it works for me.
1050 : *
1051 : * The Internet Drafts can be found if you look for
1052 : * the following:
1053 : * draft-forster-wrec-wccp-v1-00.txt
1054 : * draft-wilson-wrec-wccp-v2-01.txt
1055 : */
1056 :
1057 0 : if (!gre_wccp && !ISSET(ifp->if_flags, IFF_LINK0))
1058 0 : goto decline;
1059 :
1060 : /*
1061 : * If the first nibble of the payload does not look like
1062 : * IPv4, assume it is WCCP v2.
1063 : */
1064 0 : n = m_getptr(m, hlen, &off);
1065 0 : if (n == NULL)
1066 0 : goto decline;
1067 0 : if (n->m_data[off] >> 4 != IPVERSION)
1068 0 : hlen += sizeof(gre_wccp);
1069 :
1070 : /* FALLTHROUGH */
1071 0 : }
1072 : case htons(ETHERTYPE_IP):
1073 : #if NBPFILTER > 0
1074 : bpf_af = AF_INET;
1075 : #endif
1076 : ttloff = offsetof(struct ip, ip_ttl);
1077 : input = ipv4_input;
1078 0 : break;
1079 : #ifdef INET6
1080 : case htons(ETHERTYPE_IPV6):
1081 : #if NBPFILTER > 0
1082 : bpf_af = AF_INET6;
1083 : #endif
1084 : ttloff = offsetof(struct ip6_hdr, ip6_hlim);
1085 : input = ipv6_input;
1086 0 : break;
1087 : #endif
1088 : #ifdef MPLS
1089 : case htons(ETHERTYPE_MPLS_MCAST):
1090 0 : mcast = M_MCAST|M_BCAST;
1091 : /* fallthrough */
1092 : case htons(ETHERTYPE_MPLS):
1093 : #if NBPFILTER > 0
1094 : bpf_af = AF_MPLS;
1095 : #endif
1096 : ttloff = 3; /* XXX */
1097 : input = mpls_input;
1098 0 : break;
1099 : #endif
1100 : case htons(0):
1101 0 : if (ifp->if_type != IFT_TUNNEL) {
1102 : /* keepalives dont make sense for mgre */
1103 : goto decline;
1104 : }
1105 :
1106 : #if NBPFILTER > 0
1107 : bpf_af = AF_UNSPEC;
1108 : #endif
1109 : input = gre_keepalive_recv;
1110 0 : break;
1111 :
1112 : default:
1113 : goto decline;
1114 : }
1115 :
1116 : /* it's ours now */
1117 :
1118 0 : m_adj(m, hlen);
1119 :
1120 0 : tunnel = ifp->if_softc; /* gre and mgre tunnel info is at the front */
1121 :
1122 0 : if (tunnel->t_ttl == -1) {
1123 0 : m = m_pullup(m, ttloff + 1);
1124 0 : if (m == NULL)
1125 0 : return (IPPROTO_DONE);
1126 :
1127 0 : *(m->m_data + ttloff) = key->t_ttl;
1128 0 : }
1129 :
1130 0 : if (tunnel->t_key_mask == GRE_KEY_ENTROPY) {
1131 0 : m->m_pkthdr.ph_flowid = M_FLOWID_VALID |
1132 0 : (bemtoh32(&key->t_key) & ~GRE_KEY_ENTROPY);
1133 0 : }
1134 :
1135 0 : m->m_flags &= ~(M_MCAST|M_BCAST);
1136 0 : m->m_flags |= mcast;
1137 0 : m->m_pkthdr.ph_ifidx = ifp->if_index;
1138 0 : m->m_pkthdr.ph_rtableid = ifp->if_rdomain;
1139 :
1140 : #if NPF > 0
1141 0 : pf_pkt_addr_changed(m);
1142 : #endif
1143 :
1144 0 : ifp->if_ipackets++;
1145 0 : ifp->if_ibytes += m->m_pkthdr.len;
1146 :
1147 : #if NBPFILTER > 0
1148 0 : if (ifp->if_bpf)
1149 0 : bpf_mtap_af(ifp->if_bpf, bpf_af, m, BPF_DIRECTION_IN);
1150 : #endif
1151 :
1152 0 : (*input)(ifp, m);
1153 0 : return (IPPROTO_DONE);
1154 : decline:
1155 0 : *mp = m;
1156 0 : return (-1);
1157 0 : }
1158 :
1159 : static int
1160 0 : egre_input(const struct gre_tunnel *key, struct mbuf *m, int hlen)
1161 : {
1162 : struct egre_softc *sc;
1163 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1164 :
1165 0 : NET_ASSERT_LOCKED();
1166 0 : sc = RBT_FIND(egre_tree, &egre_tree, (const struct egre_softc *)key);
1167 0 : if (sc == NULL)
1168 0 : return (-1);
1169 :
1170 : /* it's ours now */
1171 0 : m = gre_ether_align(m, hlen);
1172 0 : if (m == NULL)
1173 0 : return (0);
1174 :
1175 0 : if (sc->sc_tunnel.t_key_mask == GRE_KEY_ENTROPY) {
1176 0 : m->m_pkthdr.ph_flowid = M_FLOWID_VALID |
1177 0 : (bemtoh32(&key->t_key) & ~GRE_KEY_ENTROPY);
1178 0 : }
1179 :
1180 0 : m->m_flags &= ~(M_MCAST|M_BCAST);
1181 :
1182 : #if NPF > 0
1183 0 : pf_pkt_addr_changed(m);
1184 : #endif
1185 :
1186 0 : ml_enqueue(&ml, m);
1187 0 : if_input(&sc->sc_ac.ac_if, &ml);
1188 :
1189 0 : return (0);
1190 0 : }
1191 :
1192 : static int
1193 0 : nvgre_rtfind(struct nvgre_softc *sc, struct ifbaconf *baconf)
1194 : {
1195 0 : struct ifnet *ifp = &sc->sc_ac.ac_if;
1196 : struct nvgre_entry *nv;
1197 0 : struct ifbareq bareq;
1198 : caddr_t uaddr, end;
1199 : int error;
1200 : int age;
1201 :
1202 0 : if (baconf->ifbac_len == 0) {
1203 : /* single read is atomic */
1204 0 : baconf->ifbac_len = sc->sc_ether_num * sizeof(bareq);
1205 0 : return (0);
1206 : }
1207 :
1208 0 : uaddr = baconf->ifbac_buf;
1209 0 : end = uaddr + baconf->ifbac_len;
1210 :
1211 0 : rw_enter_read(&sc->sc_ether_lock);
1212 0 : RBT_FOREACH(nv, nvgre_map, &sc->sc_ether_map) {
1213 0 : if (uaddr >= end)
1214 : break;
1215 :
1216 0 : memcpy(bareq.ifba_name, ifp->if_xname,
1217 : sizeof(bareq.ifba_name));
1218 0 : memcpy(bareq.ifba_ifsname, ifp->if_xname,
1219 : sizeof(bareq.ifba_ifsname));
1220 0 : memcpy(&bareq.ifba_dst, &nv->nv_dst,
1221 : sizeof(bareq.ifba_dst));
1222 :
1223 0 : memset(&bareq.ifba_dstsa, 0, sizeof(bareq.ifba_dstsa));
1224 0 : switch (sc->sc_tunnel.t_af) {
1225 : case AF_INET: {
1226 : struct sockaddr_in *sin;
1227 :
1228 0 : sin = (struct sockaddr_in *)&bareq.ifba_dstsa;
1229 0 : sin->sin_len = sizeof(*sin);
1230 0 : sin->sin_family = AF_INET;
1231 0 : sin->sin_addr = nv->nv_gateway.in4;
1232 :
1233 : break;
1234 : }
1235 : #ifdef INET6
1236 : case AF_INET6: {
1237 : struct sockaddr_in6 *sin6;
1238 :
1239 0 : sin6 = (struct sockaddr_in6 *)&bareq.ifba_dstsa;
1240 0 : sin6->sin6_len = sizeof(*sin6);
1241 0 : sin6->sin6_family = AF_INET6;
1242 0 : sin6->sin6_addr = nv->nv_gateway.in6;
1243 :
1244 : break;
1245 : }
1246 : #endif /* INET6 */
1247 : default:
1248 0 : unhandled_af(sc->sc_tunnel.t_af);
1249 : }
1250 :
1251 0 : switch (nv->nv_type) {
1252 : case NVGRE_ENTRY_DYNAMIC:
1253 0 : age = (ticks - nv->nv_age) / hz;
1254 0 : bareq.ifba_age = MIN(age, 0xff);
1255 0 : bareq.ifba_flags = IFBAF_DYNAMIC;
1256 0 : break;
1257 : case NVGRE_ENTRY_STATIC:
1258 0 : bareq.ifba_age = 0;
1259 0 : bareq.ifba_flags = IFBAF_STATIC;
1260 0 : break;
1261 : }
1262 :
1263 0 : error = copyout(&bareq, uaddr, sizeof(bareq));
1264 0 : if (error != 0) {
1265 0 : rw_exit_read(&sc->sc_ether_lock);
1266 0 : return (error);
1267 : }
1268 :
1269 0 : uaddr += sizeof(bareq);
1270 : }
1271 0 : baconf->ifbac_len = sc->sc_ether_num * sizeof(bareq);
1272 0 : rw_exit_read(&sc->sc_ether_lock);
1273 :
1274 0 : return (0);
1275 0 : }
1276 :
1277 : static void
1278 0 : nvgre_flush_map(struct nvgre_softc *sc)
1279 : {
1280 0 : struct nvgre_map map;
1281 : struct nvgre_entry *nv, *nnv;
1282 :
1283 0 : rw_enter_write(&sc->sc_ether_lock);
1284 0 : map = sc->sc_ether_map;
1285 0 : RBT_INIT(nvgre_map, &sc->sc_ether_map);
1286 0 : sc->sc_ether_num = 0;
1287 0 : rw_exit_write(&sc->sc_ether_lock);
1288 :
1289 0 : RBT_FOREACH_SAFE(nv, nvgre_map, &map, nnv) {
1290 0 : RBT_REMOVE(nvgre_map, &map, nv);
1291 0 : if (refcnt_rele(&nv->nv_refs))
1292 0 : pool_put(&nvgre_pool, nv);
1293 : }
1294 0 : }
1295 :
1296 : static void
1297 0 : nvgre_input_map(struct nvgre_softc *sc, const struct gre_tunnel *key,
1298 : const struct ether_header *eh)
1299 : {
1300 0 : struct nvgre_entry *nv, nkey;
1301 : int new = 0;
1302 :
1303 0 : if (ether_isbcast(eh->ether_shost) ||
1304 0 : ETHER_IS_MULTICAST(eh->ether_shost))
1305 0 : return;
1306 :
1307 0 : memcpy(&nkey.nv_dst, eh->ether_shost, ETHER_ADDR_LEN);
1308 :
1309 : /* remember where it came from */
1310 0 : rw_enter_read(&sc->sc_ether_lock);
1311 0 : nv = RBT_FIND(nvgre_map, &sc->sc_ether_map, &nkey);
1312 0 : if (nv == NULL)
1313 0 : new = 1;
1314 : else {
1315 0 : nv->nv_age = ticks;
1316 :
1317 0 : if (nv->nv_type != NVGRE_ENTRY_DYNAMIC ||
1318 0 : gre_ip_cmp(key->t_af, &key->t_dst, &nv->nv_gateway))
1319 0 : nv = NULL;
1320 : else
1321 0 : refcnt_take(&nv->nv_refs);
1322 : }
1323 0 : rw_exit_read(&sc->sc_ether_lock);
1324 :
1325 0 : if (new) {
1326 : struct nvgre_entry *onv;
1327 : unsigned int num;
1328 :
1329 0 : nv = pool_get(&nvgre_pool, PR_NOWAIT);
1330 0 : if (nv == NULL) {
1331 : /* oh well */
1332 0 : return;
1333 : }
1334 :
1335 0 : memcpy(&nv->nv_dst, eh->ether_shost, ETHER_ADDR_LEN);
1336 0 : nv->nv_type = NVGRE_ENTRY_DYNAMIC;
1337 0 : nv->nv_gateway = key->t_dst;
1338 0 : refcnt_init(&nv->nv_refs);
1339 0 : nv->nv_age = ticks;
1340 :
1341 0 : rw_enter_write(&sc->sc_ether_lock);
1342 0 : num = sc->sc_ether_num;
1343 0 : if (++num > sc->sc_ether_max)
1344 0 : onv = nv;
1345 : else {
1346 : /* try to give the ref to the map */
1347 0 : onv = RBT_INSERT(nvgre_map, &sc->sc_ether_map, nv);
1348 0 : if (onv == NULL) {
1349 : /* count the successful insert */
1350 0 : sc->sc_ether_num = num;
1351 0 : }
1352 : }
1353 0 : rw_exit_write(&sc->sc_ether_lock);
1354 :
1355 0 : if (onv != NULL)
1356 0 : pool_put(&nvgre_pool, nv);
1357 0 : } else if (nv != NULL) {
1358 0 : rw_enter_write(&sc->sc_ether_lock);
1359 0 : nv->nv_gateway = key->t_dst;
1360 0 : rw_exit_write(&sc->sc_ether_lock);
1361 :
1362 0 : if (refcnt_rele(&nv->nv_refs)) {
1363 : /* ioctl may have deleted the entry */
1364 0 : pool_put(&nvgre_pool, nv);
1365 0 : }
1366 : }
1367 0 : }
1368 :
1369 : static inline struct nvgre_softc *
1370 0 : nvgre_mcast_find(const struct gre_tunnel *key, unsigned int if0idx)
1371 : {
1372 : struct nvgre_softc *sc;
1373 : int rv;
1374 :
1375 : /*
1376 : * building an nvgre_softc to use with RBT_FIND is expensive, and
1377 : * would need to swap the src and dst addresses in the key. so do the
1378 : * find by hand.
1379 : */
1380 :
1381 0 : NET_ASSERT_LOCKED();
1382 0 : sc = RBT_ROOT(nvgre_mcast_tree, &nvgre_mcast_tree);
1383 0 : while (sc != NULL) {
1384 0 : rv = nvgre_cmp_mcast(key, &key->t_src, if0idx,
1385 0 : &sc->sc_tunnel, &sc->sc_tunnel.t_dst, sc->sc_ifp0);
1386 0 : if (rv == 0)
1387 0 : return (sc);
1388 0 : if (rv < 0)
1389 0 : sc = RBT_LEFT(nvgre_mcast_tree, sc);
1390 : else
1391 0 : sc = RBT_RIGHT(nvgre_mcast_tree, sc);
1392 : }
1393 :
1394 0 : return (NULL);
1395 0 : }
1396 :
1397 : static inline struct nvgre_softc *
1398 0 : nvgre_ucast_find(const struct gre_tunnel *key)
1399 : {
1400 0 : NET_ASSERT_LOCKED();
1401 0 : return (RBT_FIND(nvgre_ucast_tree, &nvgre_ucast_tree,
1402 : (struct nvgre_softc *)key));
1403 : }
1404 :
1405 : static int
1406 0 : nvgre_input(const struct gre_tunnel *key, struct mbuf *m, int hlen)
1407 : {
1408 : struct nvgre_softc *sc;
1409 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
1410 :
1411 0 : if (ISSET(m->m_flags, M_MCAST|M_BCAST))
1412 0 : sc = nvgre_mcast_find(key, m->m_pkthdr.ph_ifidx);
1413 : else
1414 0 : sc = nvgre_ucast_find(key);
1415 :
1416 0 : if (sc == NULL)
1417 0 : return (-1);
1418 :
1419 : /* it's ours now */
1420 0 : m = gre_ether_align(m, hlen);
1421 0 : if (m == NULL)
1422 0 : return (0);
1423 :
1424 0 : nvgre_input_map(sc, key, mtod(m, struct ether_header *));
1425 :
1426 0 : m->m_pkthdr.ph_flowid = M_FLOWID_VALID |
1427 0 : (bemtoh32(&key->t_key) & ~GRE_KEY_ENTROPY);
1428 :
1429 0 : m->m_flags &= ~(M_MCAST|M_BCAST);
1430 :
1431 : #if NPF > 0
1432 0 : pf_pkt_addr_changed(m);
1433 : #endif
1434 :
1435 0 : ml_enqueue(&ml, m);
1436 0 : if_input(&sc->sc_ac.ac_if, &ml);
1437 :
1438 0 : return (0);
1439 0 : }
1440 :
1441 : static struct mbuf *
1442 0 : gre_ether_align(struct mbuf *m, int hlen)
1443 : {
1444 : struct mbuf *n;
1445 0 : int off;
1446 :
1447 0 : m_adj(m, hlen);
1448 :
1449 0 : if (m->m_pkthdr.len < sizeof(struct ether_header)) {
1450 0 : m_freem(m);
1451 0 : return (NULL);
1452 : }
1453 :
1454 0 : m = m_pullup(m, sizeof(struct ether_header));
1455 0 : if (m == NULL)
1456 0 : return (NULL);
1457 :
1458 0 : n = m_getptr(m, sizeof(struct ether_header), &off);
1459 0 : if (n == NULL) {
1460 0 : m_freem(m);
1461 0 : return (NULL);
1462 : }
1463 :
1464 : if (!ALIGNED_POINTER(mtod(n, caddr_t) + off, uint32_t)) {
1465 : n = m_dup_pkt(m, ETHER_ALIGN, M_NOWAIT);
1466 : m_freem(m);
1467 : if (n == NULL)
1468 : return (NULL);
1469 : m = n;
1470 : }
1471 :
1472 0 : return (m);
1473 0 : }
1474 :
1475 : static void
1476 0 : gre_keepalive_recv(struct ifnet *ifp, struct mbuf *m)
1477 : {
1478 0 : struct gre_softc *sc = ifp->if_softc;
1479 : struct gre_keepalive *gk;
1480 0 : SIPHASH_CTX ctx;
1481 0 : uint8_t digest[SIPHASH_DIGEST_LENGTH];
1482 : int uptime, delta;
1483 0 : int tick = ticks;
1484 :
1485 0 : if (sc->sc_ka_state == GRE_KA_NONE ||
1486 0 : sc->sc_tunnel.t_rtableid != sc->sc_if.if_rdomain)
1487 : goto drop;
1488 :
1489 0 : if (m->m_pkthdr.len < sizeof(*gk))
1490 : goto drop;
1491 0 : m = m_pullup(m, sizeof(*gk));
1492 0 : if (m == NULL)
1493 0 : return;
1494 :
1495 0 : gk = mtod(m, struct gre_keepalive *);
1496 0 : uptime = bemtoh32(&gk->gk_uptime) - sc->sc_ka_bias;
1497 0 : delta = tick - uptime;
1498 0 : if (delta < 0)
1499 : goto drop;
1500 0 : if (delta > hz * 10) /* magic */
1501 : goto drop;
1502 :
1503 : /* avoid too much siphash work */
1504 0 : delta = tick - sc->sc_ka_recvtm;
1505 0 : if (delta > 0 && delta < (hz / 10))
1506 : goto drop;
1507 :
1508 0 : SipHash24_Init(&ctx, &sc->sc_ka_key);
1509 0 : SipHash24_Update(&ctx, &gk->gk_uptime, sizeof(gk->gk_uptime));
1510 0 : SipHash24_Update(&ctx, &gk->gk_random, sizeof(gk->gk_random));
1511 0 : SipHash24_Final(digest, &ctx);
1512 :
1513 0 : if (memcmp(digest, gk->gk_digest, sizeof(digest)) != 0)
1514 : goto drop;
1515 :
1516 0 : sc->sc_ka_recvtm = tick;
1517 :
1518 0 : switch (sc->sc_ka_state) {
1519 : case GRE_KA_DOWN:
1520 0 : sc->sc_ka_state = GRE_KA_HOLD;
1521 0 : sc->sc_ka_holdcnt = sc->sc_ka_holdmax;
1522 0 : sc->sc_ka_holdmax = MIN(sc->sc_ka_holdmax * 2,
1523 : 16 * sc->sc_ka_count);
1524 0 : break;
1525 : case GRE_KA_HOLD:
1526 0 : if (--sc->sc_ka_holdcnt > 0)
1527 : break;
1528 :
1529 0 : sc->sc_ka_state = GRE_KA_UP;
1530 0 : gre_link_state(&sc->sc_if, sc->sc_ka_state);
1531 0 : break;
1532 :
1533 : case GRE_KA_UP:
1534 0 : sc->sc_ka_holdmax--;
1535 0 : sc->sc_ka_holdmax = MAX(sc->sc_ka_holdmax, sc->sc_ka_count);
1536 0 : break;
1537 : }
1538 :
1539 0 : timeout_add_sec(&sc->sc_ka_hold, sc->sc_ka_timeo * sc->sc_ka_count);
1540 :
1541 : drop:
1542 0 : m_freem(m);
1543 0 : }
1544 :
1545 : static int
1546 0 : gre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
1547 : struct rtentry *rt)
1548 : {
1549 : struct m_tag *mtag;
1550 : int error = 0;
1551 :
1552 0 : if (!gre_allow) {
1553 : error = EACCES;
1554 0 : goto drop;
1555 : }
1556 :
1557 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING)) {
1558 : error = ENETDOWN;
1559 0 : goto drop;
1560 : }
1561 :
1562 0 : switch (dst->sa_family) {
1563 : case AF_INET:
1564 : #ifdef INET6
1565 : case AF_INET6:
1566 : #endif
1567 : #ifdef MPLS
1568 : case AF_MPLS:
1569 : #endif
1570 : break;
1571 : default:
1572 : error = EAFNOSUPPORT;
1573 0 : goto drop;
1574 : }
1575 :
1576 : /* Try to limit infinite recursion through misconfiguration. */
1577 0 : for (mtag = m_tag_find(m, PACKET_TAG_GRE, NULL); mtag;
1578 0 : mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) {
1579 0 : if (memcmp((caddr_t)(mtag + 1), &ifp->if_index,
1580 0 : sizeof(ifp->if_index)) == 0) {
1581 0 : m_freem(m);
1582 : error = EIO;
1583 0 : goto end;
1584 : }
1585 : }
1586 :
1587 0 : mtag = m_tag_get(PACKET_TAG_GRE, sizeof(ifp->if_index), M_NOWAIT);
1588 0 : if (mtag == NULL) {
1589 0 : m_freem(m);
1590 : error = ENOBUFS;
1591 0 : goto end;
1592 : }
1593 0 : memcpy((caddr_t)(mtag + 1), &ifp->if_index, sizeof(ifp->if_index));
1594 0 : m_tag_prepend(m, mtag);
1595 :
1596 0 : m->m_pkthdr.ph_family = dst->sa_family;
1597 :
1598 0 : error = if_enqueue(ifp, m);
1599 : end:
1600 0 : if (error)
1601 0 : ifp->if_oerrors++;
1602 0 : return (error);
1603 :
1604 : drop:
1605 0 : m_freem(m);
1606 0 : return (error);
1607 0 : }
1608 :
1609 : void
1610 0 : gre_start(struct ifnet *ifp)
1611 : {
1612 0 : struct gre_softc *sc = ifp->if_softc;
1613 : struct mbuf *m;
1614 : int af;
1615 : #if NBPFILTER > 0
1616 : caddr_t if_bpf;
1617 : #endif
1618 :
1619 0 : while ((m = ifq_dequeue(&ifp->if_snd)) != NULL) {
1620 0 : af = m->m_pkthdr.ph_family;
1621 :
1622 : #if NBPFILTER > 0
1623 0 : if_bpf = ifp->if_bpf;
1624 0 : if (if_bpf)
1625 0 : bpf_mtap_af(if_bpf, af, m, BPF_DIRECTION_OUT);
1626 : #endif
1627 :
1628 0 : m = gre_l3_encap(&sc->sc_tunnel, m, af);
1629 0 : if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) {
1630 0 : ifp->if_oerrors++;
1631 0 : continue;
1632 : }
1633 : }
1634 0 : }
1635 :
1636 : void
1637 0 : mgre_rtrequest(struct ifnet *ifp, int req, struct rtentry *rt)
1638 : {
1639 : struct ifnet *lo0ifp;
1640 : struct ifaddr *ifa, *lo0ifa;
1641 :
1642 0 : switch (req) {
1643 : case RTM_ADD:
1644 0 : if (!ISSET(rt->rt_flags, RTF_LOCAL))
1645 : break;
1646 :
1647 0 : TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
1648 0 : if (memcmp(rt_key(rt), ifa->ifa_addr,
1649 0 : rt_key(rt)->sa_len) == 0)
1650 : break;
1651 : }
1652 :
1653 0 : if (ifa == NULL)
1654 : break;
1655 :
1656 0 : KASSERT(ifa == rt->rt_ifa);
1657 :
1658 0 : lo0ifp = if_get(rtable_loindex(ifp->if_rdomain));
1659 0 : KASSERT(lo0ifp != NULL);
1660 0 : TAILQ_FOREACH(lo0ifa, &lo0ifp->if_addrlist, ifa_list) {
1661 0 : if (lo0ifa->ifa_addr->sa_family ==
1662 0 : ifa->ifa_addr->sa_family)
1663 : break;
1664 : }
1665 0 : if_put(lo0ifp);
1666 :
1667 0 : if (lo0ifa == NULL)
1668 : break;
1669 :
1670 0 : rt->rt_flags &= ~RTF_LLINFO;
1671 0 : break;
1672 : case RTM_DELETE:
1673 : case RTM_RESOLVE:
1674 : default:
1675 : break;
1676 : }
1677 0 : }
1678 :
1679 : static int
1680 0 : mgre_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dest,
1681 : struct rtentry *rt0)
1682 : {
1683 0 : struct mgre_softc *sc = ifp->if_softc;
1684 : struct sockaddr *gate;
1685 : struct rtentry *rt;
1686 : struct m_tag *mtag;
1687 : int error = 0;
1688 : sa_family_t af;
1689 : const void *addr;
1690 :
1691 0 : if (!gre_allow) {
1692 : error = EACCES;
1693 0 : goto drop;
1694 : }
1695 :
1696 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING)) {
1697 : error = ENETDOWN;
1698 0 : goto drop;
1699 : }
1700 :
1701 0 : switch (dest->sa_family) {
1702 : case AF_INET:
1703 : #ifdef INET6
1704 : case AF_INET6:
1705 : #endif
1706 : #ifdef MPLS
1707 : case AF_MPLS:
1708 : #endif
1709 : break;
1710 : default:
1711 : error = EAFNOSUPPORT;
1712 0 : goto drop;
1713 : }
1714 :
1715 0 : if (ISSET(m->m_flags, M_MCAST|M_BCAST)) {
1716 : error = ENETUNREACH;
1717 0 : goto drop;
1718 : }
1719 :
1720 0 : rt = rt_getll(rt0);
1721 :
1722 : /* chech rt_expire? */
1723 0 : if (ISSET(rt->rt_flags, RTF_REJECT)) {
1724 0 : error = (rt == rt0) ? EHOSTDOWN : EHOSTUNREACH;
1725 0 : goto drop;
1726 : }
1727 0 : if (!ISSET(rt->rt_flags, RTF_HOST)) {
1728 : error = EHOSTUNREACH;
1729 0 : goto drop;
1730 : }
1731 0 : if (ISSET(rt->rt_flags, RTF_GATEWAY)) {
1732 : error = EINVAL;
1733 0 : goto drop;
1734 : }
1735 :
1736 0 : gate = rt->rt_gateway;
1737 0 : af = gate->sa_family;
1738 0 : if (af != sc->sc_tunnel.t_af) {
1739 : error = EAGAIN;
1740 0 : goto drop;
1741 : }
1742 :
1743 : /* Try to limit infinite recursion through misconfiguration. */
1744 0 : for (mtag = m_tag_find(m, PACKET_TAG_GRE, NULL); mtag;
1745 0 : mtag = m_tag_find(m, PACKET_TAG_GRE, mtag)) {
1746 0 : if (memcmp((caddr_t)(mtag + 1), &ifp->if_index,
1747 0 : sizeof(ifp->if_index)) == 0) {
1748 : error = EIO;
1749 0 : goto drop;
1750 : }
1751 : }
1752 :
1753 0 : mtag = m_tag_get(PACKET_TAG_GRE, sizeof(ifp->if_index), M_NOWAIT);
1754 0 : if (mtag == NULL) {
1755 : error = ENOBUFS;
1756 0 : goto drop;
1757 : }
1758 0 : memcpy((caddr_t)(mtag + 1), &ifp->if_index, sizeof(ifp->if_index));
1759 0 : m_tag_prepend(m, mtag);
1760 :
1761 0 : switch (af) {
1762 : case AF_INET: {
1763 0 : struct sockaddr_in *sin = (struct sockaddr_in *)gate;
1764 0 : addr = &sin->sin_addr;
1765 : break;
1766 : }
1767 : #ifdef INET6
1768 : case AF_INET6: {
1769 0 : struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)gate;
1770 0 : addr = &sin6->sin6_addr;
1771 : break;
1772 : }
1773 : #endif
1774 : default:
1775 0 : unhandled_af(af);
1776 : /* NOTREACHED */
1777 : }
1778 :
1779 0 : m = gre_l3_encap_dst(&sc->sc_tunnel, addr, m, dest->sa_family);
1780 0 : if (m == NULL)
1781 0 : return (ENOBUFS);
1782 :
1783 0 : m->m_pkthdr.ph_family = dest->sa_family;
1784 :
1785 0 : error = if_enqueue(ifp, m);
1786 0 : if (error)
1787 0 : ifp->if_oerrors++;
1788 0 : return (error);
1789 :
1790 : drop:
1791 0 : m_freem(m);
1792 0 : return (error);
1793 0 : }
1794 :
1795 : static void
1796 0 : mgre_start(struct ifnet *ifp)
1797 : {
1798 0 : struct mgre_softc *sc = ifp->if_softc;
1799 : struct mbuf *m;
1800 : #if NBPFILTER > 0
1801 : caddr_t if_bpf;
1802 : #endif
1803 :
1804 0 : while ((m = ifq_dequeue(&ifp->if_snd)) != NULL) {
1805 : #if NBPFILTER > 0
1806 0 : if_bpf = ifp->if_bpf;
1807 0 : if (if_bpf) {
1808 0 : struct m_hdr mh;
1809 : struct mbuf *n;
1810 0 : int off;
1811 :
1812 0 : n = m_getptr(m, ifp->if_hdrlen, &off);
1813 0 : KASSERT(n != NULL);
1814 :
1815 0 : mh.mh_flags = 0;
1816 0 : mh.mh_next = n->m_next;
1817 0 : mh.mh_len = n->m_len - off;
1818 0 : mh.mh_data = n->m_data + off;
1819 :
1820 0 : bpf_mtap_af(if_bpf, m->m_pkthdr.ph_family,
1821 0 : (struct mbuf *)&mh, BPF_DIRECTION_OUT);
1822 0 : }
1823 : #endif
1824 :
1825 0 : if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) {
1826 0 : ifp->if_oerrors++;
1827 0 : continue;
1828 : }
1829 : }
1830 0 : }
1831 :
1832 : static void
1833 0 : egre_start(struct ifnet *ifp)
1834 : {
1835 0 : struct egre_softc *sc = ifp->if_softc;
1836 : struct mbuf *m0, *m;
1837 : #if NBPFILTER > 0
1838 : caddr_t if_bpf;
1839 : #endif
1840 :
1841 0 : if (!gre_allow) {
1842 0 : ifq_purge(&ifp->if_snd);
1843 0 : return;
1844 : }
1845 :
1846 0 : while ((m0 = ifq_dequeue(&ifp->if_snd)) != NULL) {
1847 : #if NBPFILTER > 0
1848 0 : if_bpf = ifp->if_bpf;
1849 0 : if (if_bpf)
1850 0 : bpf_mtap_ether(if_bpf, m0, BPF_DIRECTION_OUT);
1851 : #endif
1852 :
1853 0 : m = m_gethdr(M_DONTWAIT, m0->m_type);
1854 0 : if (m == NULL) {
1855 0 : m_freem(m0);
1856 0 : continue;
1857 : }
1858 :
1859 0 : M_MOVE_PKTHDR(m, m0);
1860 0 : m->m_next = m0;
1861 :
1862 0 : MH_ALIGN(m, 0);
1863 0 : m->m_len = 0;
1864 :
1865 0 : m = gre_encap(&sc->sc_tunnel, m, htons(ETHERTYPE_TRANSETHER),
1866 : sc->sc_tunnel.t_ttl, 0);
1867 0 : if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) {
1868 0 : ifp->if_oerrors++;
1869 0 : continue;
1870 : }
1871 : }
1872 0 : }
1873 :
1874 : static struct mbuf *
1875 0 : gre_l3_encap_dst(const struct gre_tunnel *tunnel, const void *dst,
1876 : struct mbuf *m, sa_family_t af)
1877 : {
1878 : uint16_t proto;
1879 : uint8_t ttl, tos;
1880 0 : int tttl = tunnel->t_ttl;
1881 : int ttloff;
1882 :
1883 0 : switch (af) {
1884 : case AF_INET: {
1885 : struct ip *ip;
1886 :
1887 0 : m = m_pullup(m, sizeof(*ip));
1888 0 : if (m == NULL)
1889 0 : return (NULL);
1890 :
1891 0 : ip = mtod(m, struct ip *);
1892 0 : tos = ip->ip_tos;
1893 :
1894 : ttloff = offsetof(struct ip, ip_ttl);
1895 : proto = htons(ETHERTYPE_IP);
1896 0 : break;
1897 : }
1898 : #ifdef INET6
1899 : case AF_INET6:
1900 : tos = 0;
1901 : ttloff = offsetof(struct ip6_hdr, ip6_hlim);
1902 : proto = htons(ETHERTYPE_IPV6);
1903 0 : break;
1904 : #endif
1905 : #ifdef MPLS
1906 : case AF_MPLS:
1907 : ttloff = 3;
1908 : tos = 0;
1909 :
1910 0 : if (m->m_flags & (M_BCAST | M_MCAST))
1911 0 : proto = htons(ETHERTYPE_MPLS_MCAST);
1912 : else
1913 : proto = htons(ETHERTYPE_MPLS);
1914 : break;
1915 : #endif
1916 : default:
1917 0 : unhandled_af(af);
1918 : }
1919 :
1920 0 : if (tttl == -1) {
1921 0 : m = m_pullup(m, ttloff + 1);
1922 0 : if (m == NULL)
1923 0 : return (NULL);
1924 :
1925 0 : ttl = *(m->m_data + ttloff);
1926 0 : } else
1927 0 : ttl = tttl;
1928 :
1929 0 : return (gre_encap_dst(tunnel, dst, m, proto, ttl, tos));
1930 0 : }
1931 :
1932 : static struct mbuf *
1933 0 : gre_encap_dst(const struct gre_tunnel *tunnel, const union gre_addr *dst,
1934 : struct mbuf *m, uint16_t proto, uint8_t ttl, uint8_t tos)
1935 : {
1936 : struct gre_header *gh;
1937 : struct gre_h_key *gkh;
1938 : int hlen;
1939 :
1940 : hlen = sizeof(*gh);
1941 0 : if (tunnel->t_key_mask != GRE_KEY_NONE)
1942 0 : hlen += sizeof(*gkh);
1943 :
1944 0 : m = m_prepend(m, hlen, M_DONTWAIT);
1945 0 : if (m == NULL)
1946 0 : return (NULL);
1947 :
1948 0 : gh = mtod(m, struct gre_header *);
1949 0 : gh->gre_flags = GRE_VERS_0;
1950 0 : gh->gre_proto = proto;
1951 0 : if (tunnel->t_key_mask != GRE_KEY_NONE) {
1952 0 : gh->gre_flags |= htons(GRE_KP);
1953 :
1954 0 : gkh = (struct gre_h_key *)(gh + 1);
1955 0 : gkh->gre_key = tunnel->t_key;
1956 :
1957 0 : if (tunnel->t_key_mask == GRE_KEY_ENTROPY &&
1958 0 : ISSET(m->m_pkthdr.ph_flowid, M_FLOWID_VALID)) {
1959 0 : gkh->gre_key |= htonl(~GRE_KEY_ENTROPY &
1960 : (m->m_pkthdr.ph_flowid & M_FLOWID_MASK));
1961 0 : }
1962 : }
1963 :
1964 0 : return (gre_encap_dst_ip(tunnel, dst, m, ttl, tos));
1965 0 : }
1966 :
1967 : static struct mbuf *
1968 0 : gre_encap_dst_ip(const struct gre_tunnel *tunnel, const union gre_addr *dst,
1969 : struct mbuf *m, uint8_t ttl, uint8_t tos)
1970 : {
1971 0 : switch (tunnel->t_af) {
1972 : case AF_INET: {
1973 : struct ip *ip;
1974 :
1975 0 : m = m_prepend(m, sizeof(*ip), M_DONTWAIT);
1976 0 : if (m == NULL)
1977 0 : return (NULL);
1978 :
1979 0 : ip = mtod(m, struct ip *);
1980 0 : ip->ip_v = IPVERSION;
1981 0 : ip->ip_hl = sizeof(*ip) >> 2;
1982 0 : ip->ip_off = tunnel->t_df;
1983 0 : ip->ip_tos = tos;
1984 0 : ip->ip_len = htons(m->m_pkthdr.len);
1985 0 : ip->ip_ttl = ttl;
1986 0 : ip->ip_p = IPPROTO_GRE;
1987 0 : ip->ip_src = tunnel->t_src4;
1988 0 : ip->ip_dst = dst->in4;
1989 0 : break;
1990 : }
1991 : #ifdef INET6
1992 : case AF_INET6: {
1993 : struct ip6_hdr *ip6;
1994 0 : int len = m->m_pkthdr.len;
1995 :
1996 0 : m = m_prepend(m, sizeof(*ip6), M_DONTWAIT);
1997 0 : if (m == NULL)
1998 0 : return (NULL);
1999 :
2000 0 : ip6 = mtod(m, struct ip6_hdr *);
2001 0 : ip6->ip6_flow = ISSET(m->m_pkthdr.ph_flowid, M_FLOWID_VALID) ?
2002 0 : htonl(m->m_pkthdr.ph_flowid & M_FLOWID_MASK) : 0;
2003 0 : ip6->ip6_vfc |= IPV6_VERSION;
2004 0 : ip6->ip6_plen = htons(len);
2005 0 : ip6->ip6_nxt = IPPROTO_GRE;
2006 0 : ip6->ip6_hlim = ttl;
2007 0 : ip6->ip6_src = tunnel->t_src6;
2008 0 : ip6->ip6_dst = dst->in6;
2009 :
2010 0 : if (tunnel->t_df)
2011 0 : SET(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT);
2012 :
2013 0 : break;
2014 : }
2015 : #endif /* INET6 */
2016 : default:
2017 0 : panic("%s: unsupported af %d in %p", __func__, tunnel->t_af,
2018 : tunnel);
2019 : }
2020 :
2021 0 : return (m);
2022 0 : }
2023 :
2024 : static int
2025 0 : gre_ip_output(const struct gre_tunnel *tunnel, struct mbuf *m)
2026 : {
2027 0 : m->m_flags &= ~(M_BCAST|M_MCAST);
2028 0 : m->m_pkthdr.ph_rtableid = tunnel->t_rtableid;
2029 :
2030 : #if NPF > 0
2031 0 : pf_pkt_addr_changed(m);
2032 : #endif
2033 :
2034 0 : switch (tunnel->t_af) {
2035 : case AF_INET:
2036 0 : ip_send(m);
2037 0 : break;
2038 : #ifdef INET6
2039 : case AF_INET6:
2040 0 : ip6_send(m);
2041 0 : break;
2042 : #endif
2043 : default:
2044 0 : panic("%s: unsupported af %d in %p", __func__, tunnel->t_af,
2045 : tunnel);
2046 : }
2047 :
2048 0 : return (0);
2049 : }
2050 :
2051 : static int
2052 0 : gre_tunnel_ioctl(struct ifnet *ifp, struct gre_tunnel *tunnel,
2053 : u_long cmd, void *data)
2054 : {
2055 0 : struct ifreq *ifr = (struct ifreq *)data;
2056 : int error = 0;
2057 :
2058 0 : switch(cmd) {
2059 : case SIOCSIFMTU:
2060 0 : if (ifr->ifr_mtu < 576) {
2061 : error = EINVAL;
2062 0 : break;
2063 : }
2064 0 : ifp->if_mtu = ifr->ifr_mtu;
2065 0 : break;
2066 : case SIOCADDMULTI:
2067 : case SIOCDELMULTI:
2068 : break;
2069 :
2070 : case SIOCSVNETID:
2071 0 : error = gre_set_vnetid(tunnel, ifr);
2072 0 : break;
2073 :
2074 : case SIOCGVNETID:
2075 0 : error = gre_get_vnetid(tunnel, ifr);
2076 0 : break;
2077 : case SIOCDVNETID:
2078 0 : error = gre_del_vnetid(tunnel);
2079 0 : break;
2080 :
2081 : case SIOCSVNETFLOWID:
2082 0 : error = gre_set_vnetflowid(tunnel, ifr);
2083 0 : break;
2084 :
2085 : case SIOCGVNETFLOWID:
2086 0 : error = gre_get_vnetflowid(tunnel, ifr);
2087 0 : break;
2088 :
2089 : case SIOCSLIFPHYADDR:
2090 0 : error = gre_set_tunnel(tunnel, (struct if_laddrreq *)data, 1);
2091 0 : break;
2092 : case SIOCGLIFPHYADDR:
2093 0 : error = gre_get_tunnel(tunnel, (struct if_laddrreq *)data);
2094 0 : break;
2095 : case SIOCDIFPHYADDR:
2096 0 : error = gre_del_tunnel(tunnel);
2097 0 : break;
2098 :
2099 : case SIOCSLIFPHYRTABLE:
2100 0 : if (ifr->ifr_rdomainid < 0 ||
2101 0 : ifr->ifr_rdomainid > RT_TABLEID_MAX ||
2102 0 : !rtable_exists(ifr->ifr_rdomainid)) {
2103 : error = EINVAL;
2104 0 : break;
2105 : }
2106 0 : tunnel->t_rtableid = ifr->ifr_rdomainid;
2107 0 : break;
2108 : case SIOCGLIFPHYRTABLE:
2109 0 : ifr->ifr_rdomainid = tunnel->t_rtableid;
2110 0 : break;
2111 :
2112 : case SIOCSLIFPHYDF:
2113 : /* commit */
2114 0 : tunnel->t_df = ifr->ifr_df ? htons(IP_DF) : htons(0);
2115 0 : break;
2116 : case SIOCGLIFPHYDF:
2117 0 : ifr->ifr_df = tunnel->t_df ? 1 : 0;
2118 0 : break;
2119 :
2120 : default:
2121 : error = ENOTTY;
2122 0 : break;
2123 : }
2124 :
2125 0 : return (error);
2126 : }
2127 :
2128 : static int
2129 0 : gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2130 : {
2131 0 : struct gre_softc *sc = ifp->if_softc;
2132 0 : struct ifreq *ifr = (struct ifreq *)data;
2133 0 : struct ifkalivereq *ikar = (struct ifkalivereq *)data;
2134 : int error = 0;
2135 :
2136 0 : switch(cmd) {
2137 : case SIOCSIFADDR:
2138 0 : ifp->if_flags |= IFF_UP;
2139 : /* FALLTHROUGH */
2140 : case SIOCSIFFLAGS:
2141 0 : if (ISSET(ifp->if_flags, IFF_UP)) {
2142 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
2143 0 : error = gre_up(sc);
2144 : else
2145 : error = 0;
2146 : } else {
2147 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
2148 0 : error = gre_down(sc);
2149 : }
2150 : break;
2151 : case SIOCSIFRDOMAIN:
2152 : /* let if_rdomain do its thing */
2153 : error = ENOTTY;
2154 0 : break;
2155 :
2156 : case SIOCSETKALIVE:
2157 0 : if (ikar->ikar_timeo < 0 || ikar->ikar_timeo > 86400 ||
2158 0 : ikar->ikar_cnt < 0 || ikar->ikar_cnt > 256)
2159 0 : return (EINVAL);
2160 :
2161 0 : if (ikar->ikar_timeo == 0 || ikar->ikar_cnt == 0) {
2162 0 : sc->sc_ka_count = 0;
2163 0 : sc->sc_ka_timeo = 0;
2164 0 : sc->sc_ka_state = GRE_KA_NONE;
2165 0 : } else {
2166 0 : sc->sc_ka_count = ikar->ikar_cnt;
2167 0 : sc->sc_ka_timeo = ikar->ikar_timeo;
2168 0 : sc->sc_ka_state = GRE_KA_DOWN;
2169 : }
2170 : break;
2171 :
2172 : case SIOCGETKALIVE:
2173 0 : ikar->ikar_cnt = sc->sc_ka_count;
2174 0 : ikar->ikar_timeo = sc->sc_ka_timeo;
2175 0 : break;
2176 :
2177 : case SIOCSLIFPHYTTL:
2178 0 : if (ifr->ifr_ttl != -1 &&
2179 0 : (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff)) {
2180 : error = EINVAL;
2181 0 : break;
2182 : }
2183 :
2184 : /* commit */
2185 0 : sc->sc_tunnel.t_ttl = ifr->ifr_ttl;
2186 0 : break;
2187 :
2188 : case SIOCGLIFPHYTTL:
2189 0 : ifr->ifr_ttl = sc->sc_tunnel.t_ttl;
2190 0 : break;
2191 :
2192 : default:
2193 0 : error = gre_tunnel_ioctl(ifp, &sc->sc_tunnel, cmd, data);
2194 0 : break;
2195 : }
2196 :
2197 0 : return (error);
2198 0 : }
2199 :
2200 : static int
2201 0 : mgre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2202 : {
2203 0 : struct mgre_softc *sc = ifp->if_softc;
2204 0 : struct ifreq *ifr = (struct ifreq *)data;
2205 : int error = 0;
2206 :
2207 0 : switch(cmd) {
2208 : case SIOCSIFADDR:
2209 : break;
2210 : case SIOCSIFFLAGS:
2211 0 : if (ISSET(ifp->if_flags, IFF_UP)) {
2212 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
2213 0 : error = mgre_up(sc);
2214 : else
2215 : error = 0;
2216 : } else {
2217 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
2218 0 : error = mgre_down(sc);
2219 : }
2220 : break;
2221 :
2222 : case SIOCSLIFPHYTTL:
2223 0 : if (ifr->ifr_ttl != -1 &&
2224 0 : (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff)) {
2225 : error = EINVAL;
2226 0 : break;
2227 : }
2228 :
2229 : /* commit */
2230 0 : sc->sc_tunnel.t_ttl = ifr->ifr_ttl;
2231 0 : break;
2232 :
2233 : case SIOCGLIFPHYTTL:
2234 0 : ifr->ifr_ttl = sc->sc_tunnel.t_ttl;
2235 0 : break;
2236 :
2237 : case SIOCSLIFPHYADDR:
2238 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2239 : error = EBUSY;
2240 0 : break;
2241 : }
2242 0 : error = mgre_set_tunnel(sc, (struct if_laddrreq *)data);
2243 0 : break;
2244 : case SIOCGLIFPHYADDR:
2245 0 : error = mgre_get_tunnel(sc, (struct if_laddrreq *)data);
2246 0 : break;
2247 :
2248 : case SIOCSVNETID:
2249 : case SIOCDVNETID:
2250 : case SIOCDIFPHYADDR:
2251 : case SIOCSLIFPHYRTABLE:
2252 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2253 : error = EBUSY;
2254 0 : break;
2255 : }
2256 :
2257 : /* FALLTHROUGH */
2258 : default:
2259 0 : error = gre_tunnel_ioctl(ifp, &sc->sc_tunnel, cmd, data);
2260 0 : break;
2261 : }
2262 :
2263 0 : return (error);
2264 : }
2265 :
2266 : static int
2267 0 : mgre_set_tunnel(struct mgre_softc *sc, struct if_laddrreq *req)
2268 : {
2269 0 : struct gre_tunnel *tunnel = &sc->sc_tunnel;
2270 0 : struct sockaddr *addr = (struct sockaddr *)&req->addr;
2271 0 : struct sockaddr *dstaddr = (struct sockaddr *)&req->dstaddr;
2272 : struct sockaddr_in *addr4;
2273 : #ifdef INET6
2274 : struct sockaddr_in6 *addr6;
2275 : int error;
2276 : #endif
2277 :
2278 0 : if (dstaddr->sa_family != AF_UNSPEC)
2279 0 : return (EINVAL);
2280 :
2281 : /* validate */
2282 0 : switch (addr->sa_family) {
2283 : case AF_INET:
2284 0 : if (addr->sa_len != sizeof(*addr4))
2285 0 : return (EINVAL);
2286 :
2287 0 : addr4 = (struct sockaddr_in *)addr;
2288 0 : if (in_nullhost(addr4->sin_addr) ||
2289 0 : IN_MULTICAST(addr4->sin_addr.s_addr))
2290 0 : return (EINVAL);
2291 :
2292 0 : tunnel->t_src4 = addr4->sin_addr;
2293 0 : tunnel->t_dst4.s_addr = INADDR_ANY;
2294 :
2295 0 : break;
2296 : #ifdef INET6
2297 : case AF_INET6:
2298 0 : if (addr->sa_len != sizeof(*addr6))
2299 0 : return (EINVAL);
2300 :
2301 0 : addr6 = (struct sockaddr_in6 *)addr;
2302 0 : if (IN6_IS_ADDR_UNSPECIFIED(&addr6->sin6_addr) ||
2303 0 : IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr))
2304 0 : return (EINVAL);
2305 :
2306 0 : error = in6_embedscope(&tunnel->t_src6, addr6, NULL);
2307 0 : if (error != 0)
2308 0 : return (error);
2309 :
2310 0 : memset(&tunnel->t_dst6, 0, sizeof(tunnel->t_dst6));
2311 :
2312 0 : break;
2313 : #endif
2314 : default:
2315 0 : return (EAFNOSUPPORT);
2316 : }
2317 :
2318 : /* commit */
2319 0 : tunnel->t_af = addr->sa_family;
2320 :
2321 0 : return (0);
2322 0 : }
2323 :
2324 : static int
2325 0 : mgre_get_tunnel(struct mgre_softc *sc, struct if_laddrreq *req)
2326 : {
2327 0 : struct gre_tunnel *tunnel = &sc->sc_tunnel;
2328 0 : struct sockaddr *dstaddr = (struct sockaddr *)&req->dstaddr;
2329 : struct sockaddr_in *sin;
2330 : #ifdef INET6
2331 : struct sockaddr_in6 *sin6;
2332 : #endif
2333 :
2334 0 : switch (tunnel->t_af) {
2335 : case AF_UNSPEC:
2336 0 : return (EADDRNOTAVAIL);
2337 : case AF_INET:
2338 0 : sin = (struct sockaddr_in *)&req->addr;
2339 0 : memset(sin, 0, sizeof(*sin));
2340 0 : sin->sin_family = AF_INET;
2341 0 : sin->sin_len = sizeof(*sin);
2342 0 : sin->sin_addr = tunnel->t_src4;
2343 0 : break;
2344 :
2345 : #ifdef INET6
2346 : case AF_INET6:
2347 0 : sin6 = (struct sockaddr_in6 *)&req->addr;
2348 0 : memset(sin6, 0, sizeof(*sin6));
2349 0 : sin6->sin6_family = AF_INET6;
2350 0 : sin6->sin6_len = sizeof(*sin6);
2351 0 : in6_recoverscope(sin6, &tunnel->t_src6);
2352 0 : break;
2353 : #endif
2354 : default:
2355 0 : unhandled_af(tunnel->t_af);
2356 : }
2357 :
2358 0 : dstaddr->sa_len = 2;
2359 0 : dstaddr->sa_family = AF_UNSPEC;
2360 :
2361 0 : return (0);
2362 0 : }
2363 :
2364 : static int
2365 0 : egre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2366 : {
2367 0 : struct egre_softc *sc = ifp->if_softc;
2368 0 : struct ifreq *ifr = (struct ifreq *)data;
2369 : int error = 0;
2370 :
2371 0 : switch(cmd) {
2372 : case SIOCSIFADDR:
2373 : break;
2374 : case SIOCSIFFLAGS:
2375 0 : if (ISSET(ifp->if_flags, IFF_UP)) {
2376 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
2377 0 : error = egre_up(sc);
2378 : else
2379 : error = 0;
2380 : } else {
2381 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
2382 0 : error = egre_down(sc);
2383 : }
2384 : break;
2385 :
2386 : case SIOCSLIFPHYTTL:
2387 0 : if (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff) {
2388 : error = EINVAL;
2389 0 : break;
2390 : }
2391 :
2392 : /* commit */
2393 0 : sc->sc_tunnel.t_ttl = (uint8_t)ifr->ifr_ttl;
2394 0 : break;
2395 :
2396 : case SIOCGLIFPHYTTL:
2397 0 : ifr->ifr_ttl = (int)sc->sc_tunnel.t_ttl;
2398 0 : break;
2399 :
2400 : case SIOCSVNETID:
2401 : case SIOCDVNETID:
2402 : case SIOCSVNETFLOWID:
2403 : case SIOCSLIFPHYADDR:
2404 : case SIOCDIFPHYADDR:
2405 : case SIOCSLIFPHYRTABLE:
2406 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2407 : error = EBUSY;
2408 0 : break;
2409 : }
2410 :
2411 : /* FALLTHROUGH */
2412 : default:
2413 0 : error = gre_tunnel_ioctl(ifp, &sc->sc_tunnel, cmd, data);
2414 0 : if (error == ENOTTY)
2415 0 : error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
2416 : break;
2417 : }
2418 :
2419 0 : return (error);
2420 : }
2421 :
2422 : static int
2423 0 : nvgre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2424 : {
2425 0 : struct nvgre_softc *sc = ifp->if_softc;
2426 0 : struct gre_tunnel *tunnel = &sc->sc_tunnel;
2427 :
2428 0 : struct ifreq *ifr = (struct ifreq *)data;
2429 0 : struct if_parent *parent = (struct if_parent *)data;
2430 0 : struct ifbrparam *bparam = (struct ifbrparam *)data;
2431 : struct ifnet *ifp0;
2432 :
2433 : int error = 0;
2434 :
2435 0 : switch (cmd) {
2436 : case SIOCSIFADDR:
2437 : break;
2438 : case SIOCSIFFLAGS:
2439 0 : if (ISSET(ifp->if_flags, IFF_UP)) {
2440 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
2441 0 : error = nvgre_up(sc);
2442 : else
2443 : error = ENETRESET;
2444 : } else {
2445 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
2446 0 : error = nvgre_down(sc);
2447 : }
2448 : break;
2449 :
2450 : case SIOCSLIFPHYADDR:
2451 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2452 : error = EBUSY;
2453 0 : break;
2454 : }
2455 0 : error = gre_set_tunnel(tunnel, (struct if_laddrreq *)data, 0);
2456 0 : if (error == 0)
2457 0 : nvgre_flush_map(sc);
2458 : break;
2459 : case SIOCGLIFPHYADDR:
2460 0 : error = gre_get_tunnel(tunnel, (struct if_laddrreq *)data);
2461 0 : break;
2462 : case SIOCDIFPHYADDR:
2463 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2464 : error = EBUSY;
2465 0 : break;
2466 : }
2467 0 : error = gre_del_tunnel(tunnel);
2468 0 : if (error == 0)
2469 0 : nvgre_flush_map(sc);
2470 : break;
2471 :
2472 : case SIOCSIFPARENT:
2473 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2474 : error = EBUSY;
2475 0 : break;
2476 : }
2477 0 : error = nvgre_set_parent(sc, parent->ifp_parent);
2478 0 : if (error == 0)
2479 0 : nvgre_flush_map(sc);
2480 : break;
2481 : case SIOCGIFPARENT:
2482 0 : ifp0 = if_get(sc->sc_ifp0);
2483 0 : if (ifp0 == NULL)
2484 0 : error = EADDRNOTAVAIL;
2485 : else {
2486 0 : memcpy(parent->ifp_parent, ifp0->if_xname,
2487 : sizeof(parent->ifp_parent));
2488 : }
2489 0 : if_put(ifp0);
2490 0 : break;
2491 : case SIOCDIFPARENT:
2492 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2493 : error = EBUSY;
2494 0 : break;
2495 : }
2496 : /* commit */
2497 0 : sc->sc_ifp0 = 0;
2498 0 : nvgre_flush_map(sc);
2499 0 : break;
2500 :
2501 : case SIOCSVNETID:
2502 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2503 : error = EBUSY;
2504 0 : break;
2505 : }
2506 0 : if (ifr->ifr_vnetid < GRE_KEY_ENTROPY_MIN ||
2507 0 : ifr->ifr_vnetid > GRE_KEY_ENTROPY_MAX) {
2508 : error = EINVAL;
2509 0 : break;
2510 : }
2511 :
2512 : /* commit */
2513 0 : tunnel->t_key = htonl(ifr->ifr_vnetid << GRE_KEY_ENTROPY_SHIFT);
2514 0 : nvgre_flush_map(sc);
2515 0 : break;
2516 : case SIOCGVNETID:
2517 0 : error = gre_get_vnetid(tunnel, ifr);
2518 0 : break;
2519 :
2520 : case SIOCSLIFPHYRTABLE:
2521 0 : if (ifr->ifr_rdomainid < 0 ||
2522 0 : ifr->ifr_rdomainid > RT_TABLEID_MAX ||
2523 0 : !rtable_exists(ifr->ifr_rdomainid)) {
2524 : error = EINVAL;
2525 0 : break;
2526 : }
2527 0 : tunnel->t_rtableid = ifr->ifr_rdomainid;
2528 0 : nvgre_flush_map(sc);
2529 0 : break;
2530 : case SIOCGLIFPHYRTABLE:
2531 0 : ifr->ifr_rdomainid = tunnel->t_rtableid;
2532 0 : break;
2533 :
2534 : case SIOCSLIFPHYDF:
2535 : /* commit */
2536 0 : tunnel->t_df = ifr->ifr_df ? htons(IP_DF) : htons(0);
2537 0 : break;
2538 : case SIOCGLIFPHYDF:
2539 0 : ifr->ifr_df = tunnel->t_df ? 1 : 0;
2540 0 : break;
2541 :
2542 : case SIOCSLIFPHYTTL:
2543 0 : if (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff) {
2544 : error = EINVAL;
2545 0 : break;
2546 : }
2547 :
2548 : /* commit */
2549 0 : tunnel->t_ttl = ifr->ifr_ttl;
2550 0 : break;
2551 :
2552 : case SIOCGLIFPHYTTL:
2553 0 : ifr->ifr_ttl = tunnel->t_ttl;
2554 0 : break;
2555 :
2556 : case SIOCBRDGSCACHE:
2557 0 : if (bparam->ifbrp_csize < 1) {
2558 : error = EINVAL;
2559 0 : break;
2560 : }
2561 :
2562 : /* commit */
2563 0 : sc->sc_ether_max = bparam->ifbrp_csize;
2564 0 : break;
2565 : case SIOCBRDGGCACHE:
2566 0 : bparam->ifbrp_csize = sc->sc_ether_max;
2567 0 : break;
2568 :
2569 : case SIOCBRDGSTO:
2570 0 : if (bparam->ifbrp_ctime < 0 ||
2571 0 : bparam->ifbrp_ctime > INT_MAX / hz) {
2572 : error = EINVAL;
2573 0 : break;
2574 : }
2575 0 : sc->sc_ether_tmo = bparam->ifbrp_ctime * hz;
2576 0 : break;
2577 : case SIOCBRDGGTO:
2578 0 : bparam->ifbrp_ctime = sc->sc_ether_tmo / hz;
2579 0 : break;
2580 :
2581 : case SIOCBRDGRTS:
2582 0 : error = nvgre_rtfind(sc, (struct ifbaconf *)data);
2583 0 : break;
2584 : case SIOCBRDGFLUSH:
2585 0 : nvgre_flush_map(sc);
2586 0 : break;
2587 :
2588 : default:
2589 0 : error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
2590 0 : break;
2591 : }
2592 :
2593 0 : if (error == ENETRESET) {
2594 : /* no hardware to program */
2595 : error = 0;
2596 0 : }
2597 :
2598 0 : return (error);
2599 : }
2600 :
2601 : static int
2602 0 : eoip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
2603 : {
2604 0 : struct eoip_softc *sc = ifp->if_softc;
2605 0 : struct ifreq *ifr = (struct ifreq *)data;
2606 0 : struct ifkalivereq *ikar = (struct ifkalivereq *)data;
2607 : int error = 0;
2608 :
2609 0 : switch(cmd) {
2610 : case SIOCSIFADDR:
2611 : break;
2612 : case SIOCSIFFLAGS:
2613 0 : if (ISSET(ifp->if_flags, IFF_UP)) {
2614 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
2615 0 : error = eoip_up(sc);
2616 : else
2617 : error = 0;
2618 : } else {
2619 0 : if (ISSET(ifp->if_flags, IFF_RUNNING))
2620 0 : error = eoip_down(sc);
2621 : }
2622 : break;
2623 :
2624 : case SIOCSETKALIVE:
2625 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2626 : error = EBUSY;
2627 0 : break;
2628 : }
2629 :
2630 0 : if (ikar->ikar_timeo < 0 || ikar->ikar_timeo > 86400 ||
2631 0 : ikar->ikar_cnt < 0 || ikar->ikar_cnt > 256)
2632 0 : return (EINVAL);
2633 :
2634 0 : if (ikar->ikar_timeo == 0 || ikar->ikar_cnt == 0) {
2635 0 : sc->sc_ka_count = 0;
2636 0 : sc->sc_ka_timeo = 0;
2637 0 : sc->sc_ka_state = GRE_KA_NONE;
2638 0 : } else {
2639 0 : sc->sc_ka_count = ikar->ikar_cnt;
2640 0 : sc->sc_ka_timeo = ikar->ikar_timeo;
2641 0 : sc->sc_ka_state = GRE_KA_DOWN;
2642 : }
2643 : break;
2644 :
2645 : case SIOCGETKALIVE:
2646 0 : ikar->ikar_cnt = sc->sc_ka_count;
2647 0 : ikar->ikar_timeo = sc->sc_ka_timeo;
2648 0 : break;
2649 :
2650 : case SIOCSVNETID:
2651 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2652 : error = EBUSY;
2653 0 : break;
2654 : }
2655 0 : if (ifr->ifr_vnetid < 0 || ifr->ifr_vnetid > 0xffff)
2656 0 : return (EINVAL);
2657 :
2658 0 : sc->sc_tunnel.t_key = htole16(ifr->ifr_vnetid); /* for cmp */
2659 0 : sc->sc_tunnel_id = htole16(ifr->ifr_vnetid);
2660 0 : break;
2661 :
2662 : case SIOCGVNETID:
2663 0 : ifr->ifr_vnetid = letoh16(sc->sc_tunnel_id);
2664 0 : break;
2665 :
2666 : case SIOCSLIFPHYADDR:
2667 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2668 : error = EBUSY;
2669 0 : break;
2670 : }
2671 :
2672 0 : error = gre_set_tunnel(&sc->sc_tunnel,
2673 0 : (struct if_laddrreq *)data, 1);
2674 0 : break;
2675 : case SIOCGLIFPHYADDR:
2676 0 : error = gre_get_tunnel(&sc->sc_tunnel,
2677 0 : (struct if_laddrreq *)data);
2678 0 : break;
2679 : case SIOCDIFPHYADDR:
2680 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2681 : error = EBUSY;
2682 0 : break;
2683 : }
2684 :
2685 0 : error = gre_del_tunnel(&sc->sc_tunnel);
2686 0 : break;
2687 :
2688 : case SIOCSLIFPHYRTABLE:
2689 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2690 : error = EBUSY;
2691 0 : break;
2692 : }
2693 :
2694 0 : if (ifr->ifr_rdomainid < 0 ||
2695 0 : ifr->ifr_rdomainid > RT_TABLEID_MAX ||
2696 0 : !rtable_exists(ifr->ifr_rdomainid)) {
2697 : error = EINVAL;
2698 0 : break;
2699 : }
2700 0 : sc->sc_tunnel.t_rtableid = ifr->ifr_rdomainid;
2701 0 : break;
2702 : case SIOCGLIFPHYRTABLE:
2703 0 : ifr->ifr_rdomainid = sc->sc_tunnel.t_rtableid;
2704 0 : break;
2705 :
2706 : case SIOCSLIFPHYTTL:
2707 0 : if (ifr->ifr_ttl < 1 || ifr->ifr_ttl > 0xff) {
2708 : error = EINVAL;
2709 0 : break;
2710 : }
2711 :
2712 : /* commit */
2713 0 : sc->sc_tunnel.t_ttl = (uint8_t)ifr->ifr_ttl;
2714 0 : break;
2715 : case SIOCGLIFPHYTTL:
2716 0 : ifr->ifr_ttl = (int)sc->sc_tunnel.t_ttl;
2717 0 : break;
2718 :
2719 : case SIOCSLIFPHYDF:
2720 : /* commit */
2721 0 : sc->sc_tunnel.t_df = ifr->ifr_df ? htons(IP_DF) : htons(0);
2722 0 : break;
2723 : case SIOCGLIFPHYDF:
2724 0 : ifr->ifr_df = sc->sc_tunnel.t_df ? 1 : 0;
2725 0 : break;
2726 :
2727 : default:
2728 0 : error = ether_ioctl(ifp, &sc->sc_ac, cmd, data);
2729 0 : break;
2730 : }
2731 :
2732 0 : return (error);
2733 0 : }
2734 :
2735 : static int
2736 0 : gre_up(struct gre_softc *sc)
2737 : {
2738 0 : NET_ASSERT_LOCKED();
2739 0 : SET(sc->sc_if.if_flags, IFF_RUNNING);
2740 :
2741 0 : if (sc->sc_ka_state != GRE_KA_NONE) {
2742 0 : arc4random_buf(&sc->sc_ka_key, sizeof(sc->sc_ka_key));
2743 0 : sc->sc_ka_bias = arc4random();
2744 :
2745 0 : sc->sc_ka_recvtm = ticks - hz;
2746 0 : sc->sc_ka_holdmax = sc->sc_ka_count;
2747 :
2748 0 : gre_keepalive_send(sc);
2749 0 : }
2750 :
2751 0 : return (0);
2752 : }
2753 :
2754 : static int
2755 0 : gre_down(struct gre_softc *sc)
2756 : {
2757 0 : NET_ASSERT_LOCKED();
2758 0 : CLR(sc->sc_if.if_flags, IFF_RUNNING);
2759 :
2760 0 : if (sc->sc_ka_state != GRE_KA_NONE) {
2761 0 : if (!timeout_del(&sc->sc_ka_hold))
2762 0 : timeout_barrier(&sc->sc_ka_hold);
2763 0 : if (!timeout_del(&sc->sc_ka_send))
2764 0 : timeout_barrier(&sc->sc_ka_send);
2765 :
2766 0 : sc->sc_ka_state = GRE_KA_DOWN;
2767 0 : gre_link_state(&sc->sc_if, sc->sc_ka_state);
2768 0 : }
2769 :
2770 0 : return (0);
2771 : }
2772 :
2773 : static void
2774 0 : gre_link_state(struct ifnet *ifp, unsigned int state)
2775 : {
2776 : int link_state = LINK_STATE_UNKNOWN;
2777 :
2778 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
2779 0 : switch (state) {
2780 : case GRE_KA_NONE:
2781 : /* maybe up? or down? it's unknown, really */
2782 : break;
2783 : case GRE_KA_UP:
2784 : link_state = LINK_STATE_UP;
2785 0 : break;
2786 : default:
2787 : link_state = LINK_STATE_KALIVE_DOWN;
2788 0 : break;
2789 : }
2790 : }
2791 :
2792 0 : if (ifp->if_link_state != link_state) {
2793 0 : ifp->if_link_state = link_state;
2794 0 : if_link_state_change(ifp);
2795 0 : }
2796 0 : }
2797 :
2798 : static void
2799 0 : gre_keepalive_send(void *arg)
2800 : {
2801 0 : struct gre_tunnel t;
2802 0 : struct gre_softc *sc = arg;
2803 : struct mbuf *m;
2804 : struct gre_keepalive *gk;
2805 0 : SIPHASH_CTX ctx;
2806 : int linkhdr, len;
2807 : uint16_t proto;
2808 : uint8_t ttl;
2809 :
2810 0 : if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING) ||
2811 0 : sc->sc_ka_state == GRE_KA_NONE ||
2812 0 : sc->sc_tunnel.t_rtableid != sc->sc_if.if_rdomain)
2813 0 : return;
2814 :
2815 : /* this is really conservative */
2816 : #ifdef INET6
2817 0 : linkhdr = max_linkhdr + MAX(sizeof(struct ip), sizeof(struct ip6_hdr)) +
2818 0 : sizeof(struct gre_header) + sizeof(struct gre_h_key);
2819 : #else
2820 : linkhdr = max_linkhdr + sizeof(struct ip) +
2821 : sizeof(struct gre_header) + sizeof(struct gre_h_key);
2822 : #endif
2823 0 : len = linkhdr + sizeof(*gk);
2824 :
2825 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
2826 0 : if (m == NULL)
2827 0 : return;
2828 :
2829 0 : if (len > MHLEN) {
2830 0 : MCLGETI(m, M_DONTWAIT, NULL, len);
2831 0 : if (!ISSET(m->m_flags, M_EXT)) {
2832 0 : m_freem(m);
2833 0 : return;
2834 : }
2835 : }
2836 :
2837 0 : m->m_pkthdr.len = m->m_len = len;
2838 0 : m_adj(m, linkhdr);
2839 :
2840 : /*
2841 : * build the inside packet
2842 : */
2843 0 : gk = mtod(m, struct gre_keepalive *);
2844 0 : htobem32(&gk->gk_uptime, sc->sc_ka_bias + ticks);
2845 0 : htobem32(&gk->gk_random, arc4random());
2846 :
2847 0 : SipHash24_Init(&ctx, &sc->sc_ka_key);
2848 0 : SipHash24_Update(&ctx, &gk->gk_uptime, sizeof(gk->gk_uptime));
2849 0 : SipHash24_Update(&ctx, &gk->gk_random, sizeof(gk->gk_random));
2850 0 : SipHash24_Final(gk->gk_digest, &ctx);
2851 :
2852 0 : ttl = sc->sc_tunnel.t_ttl == -1 ? ip_defttl : sc->sc_tunnel.t_ttl;
2853 :
2854 0 : t.t_af = sc->sc_tunnel.t_af;
2855 0 : t.t_df = sc->sc_tunnel.t_df;
2856 0 : t.t_src = sc->sc_tunnel.t_dst;
2857 0 : t.t_dst = sc->sc_tunnel.t_src;
2858 0 : t.t_key = sc->sc_tunnel.t_key;
2859 0 : t.t_key_mask = sc->sc_tunnel.t_key_mask;
2860 :
2861 0 : m = gre_encap(&t, m, htons(0), ttl, IPTOS_PREC_INTERNETCONTROL);
2862 0 : if (m == NULL)
2863 0 : return;
2864 :
2865 0 : switch (sc->sc_tunnel.t_af) {
2866 : case AF_INET: {
2867 : struct ip *ip;
2868 :
2869 0 : ip = mtod(m, struct ip *);
2870 0 : ip->ip_id = htons(ip_randomid());
2871 0 : ip->ip_sum = 0;
2872 0 : ip->ip_sum = in_cksum(m, sizeof(*ip));
2873 :
2874 : proto = htons(ETHERTYPE_IP);
2875 : break;
2876 : }
2877 : #ifdef INET6
2878 : case AF_INET6:
2879 : proto = htons(ETHERTYPE_IPV6);
2880 0 : break;
2881 : #endif
2882 : }
2883 :
2884 : /*
2885 : * put it in the tunnel
2886 : */
2887 0 : m = gre_encap(&sc->sc_tunnel, m, proto, ttl,
2888 : IPTOS_PREC_INTERNETCONTROL);
2889 0 : if (m == NULL)
2890 0 : return;
2891 :
2892 0 : gre_ip_output(&sc->sc_tunnel, m);
2893 :
2894 0 : timeout_add_sec(&sc->sc_ka_send, sc->sc_ka_timeo);
2895 0 : }
2896 :
2897 : static void
2898 0 : gre_keepalive_hold(void *arg)
2899 : {
2900 0 : struct gre_softc *sc = arg;
2901 0 : struct ifnet *ifp = &sc->sc_if;
2902 :
2903 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING) ||
2904 0 : sc->sc_ka_state == GRE_KA_NONE)
2905 0 : return;
2906 :
2907 0 : NET_LOCK();
2908 0 : sc->sc_ka_state = GRE_KA_DOWN;
2909 0 : gre_link_state(ifp, sc->sc_ka_state);
2910 0 : NET_UNLOCK();
2911 0 : }
2912 :
2913 : static int
2914 0 : gre_set_tunnel(struct gre_tunnel *tunnel, struct if_laddrreq *req, int ucast)
2915 : {
2916 0 : struct sockaddr *src = (struct sockaddr *)&req->addr;
2917 0 : struct sockaddr *dst = (struct sockaddr *)&req->dstaddr;
2918 : struct sockaddr_in *src4, *dst4;
2919 : #ifdef INET6
2920 : struct sockaddr_in6 *src6, *dst6;
2921 : int error;
2922 : #endif
2923 :
2924 : /* sa_family and sa_len must be equal */
2925 0 : if (src->sa_family != dst->sa_family || src->sa_len != dst->sa_len)
2926 0 : return (EINVAL);
2927 :
2928 : /* validate */
2929 0 : switch (dst->sa_family) {
2930 : case AF_INET:
2931 0 : if (dst->sa_len != sizeof(*dst4))
2932 0 : return (EINVAL);
2933 :
2934 0 : src4 = (struct sockaddr_in *)src;
2935 0 : if (in_nullhost(src4->sin_addr) ||
2936 0 : IN_MULTICAST(src4->sin_addr.s_addr))
2937 0 : return (EINVAL);
2938 :
2939 0 : dst4 = (struct sockaddr_in *)dst;
2940 0 : if (in_nullhost(dst4->sin_addr) ||
2941 0 : (IN_MULTICAST(dst4->sin_addr.s_addr) != !ucast))
2942 0 : return (EINVAL);
2943 :
2944 0 : tunnel->t_src4 = src4->sin_addr;
2945 0 : tunnel->t_dst4 = dst4->sin_addr;
2946 :
2947 0 : break;
2948 : #ifdef INET6
2949 : case AF_INET6:
2950 0 : if (dst->sa_len != sizeof(*dst6))
2951 0 : return (EINVAL);
2952 :
2953 0 : src6 = (struct sockaddr_in6 *)src;
2954 0 : if (IN6_IS_ADDR_UNSPECIFIED(&src6->sin6_addr) ||
2955 0 : IN6_IS_ADDR_MULTICAST(&src6->sin6_addr))
2956 0 : return (EINVAL);
2957 :
2958 0 : dst6 = (struct sockaddr_in6 *)dst;
2959 0 : if (IN6_IS_ADDR_UNSPECIFIED(&dst6->sin6_addr) ||
2960 0 : IN6_IS_ADDR_MULTICAST(&dst6->sin6_addr) != !ucast)
2961 0 : return (EINVAL);
2962 :
2963 0 : if (src6->sin6_scope_id != dst6->sin6_scope_id)
2964 0 : return (EINVAL);
2965 :
2966 0 : error = in6_embedscope(&tunnel->t_src6, src6, NULL);
2967 0 : if (error != 0)
2968 0 : return (error);
2969 :
2970 0 : error = in6_embedscope(&tunnel->t_dst6, dst6, NULL);
2971 0 : if (error != 0)
2972 0 : return (error);
2973 :
2974 : break;
2975 : #endif
2976 : default:
2977 0 : return (EAFNOSUPPORT);
2978 : }
2979 :
2980 : /* commit */
2981 0 : tunnel->t_af = dst->sa_family;
2982 :
2983 0 : return (0);
2984 0 : }
2985 :
2986 : static int
2987 0 : gre_get_tunnel(struct gre_tunnel *tunnel, struct if_laddrreq *req)
2988 : {
2989 0 : struct sockaddr *src = (struct sockaddr *)&req->addr;
2990 0 : struct sockaddr *dst = (struct sockaddr *)&req->dstaddr;
2991 : struct sockaddr_in *sin;
2992 : #ifdef INET6 /* ifconfig already embeds the scopeid */
2993 : struct sockaddr_in6 *sin6;
2994 : #endif
2995 :
2996 0 : switch (tunnel->t_af) {
2997 : case AF_UNSPEC:
2998 0 : return (EADDRNOTAVAIL);
2999 : case AF_INET:
3000 0 : sin = (struct sockaddr_in *)src;
3001 0 : memset(sin, 0, sizeof(*sin));
3002 0 : sin->sin_family = AF_INET;
3003 0 : sin->sin_len = sizeof(*sin);
3004 0 : sin->sin_addr = tunnel->t_src4;
3005 :
3006 0 : sin = (struct sockaddr_in *)dst;
3007 0 : memset(sin, 0, sizeof(*sin));
3008 0 : sin->sin_family = AF_INET;
3009 0 : sin->sin_len = sizeof(*sin);
3010 0 : sin->sin_addr = tunnel->t_dst4;
3011 :
3012 0 : break;
3013 :
3014 : #ifdef INET6
3015 : case AF_INET6:
3016 0 : sin6 = (struct sockaddr_in6 *)src;
3017 0 : memset(sin6, 0, sizeof(*sin6));
3018 0 : sin6->sin6_family = AF_INET6;
3019 0 : sin6->sin6_len = sizeof(*sin6);
3020 0 : in6_recoverscope(sin6, &tunnel->t_src6);
3021 :
3022 0 : sin6 = (struct sockaddr_in6 *)dst;
3023 0 : memset(sin6, 0, sizeof(*sin6));
3024 0 : sin6->sin6_family = AF_INET6;
3025 0 : sin6->sin6_len = sizeof(*sin6);
3026 0 : in6_recoverscope(sin6, &tunnel->t_dst6);
3027 :
3028 0 : break;
3029 : #endif
3030 : default:
3031 0 : return (EAFNOSUPPORT);
3032 : }
3033 :
3034 0 : return (0);
3035 0 : }
3036 :
3037 : static int
3038 0 : gre_del_tunnel(struct gre_tunnel *tunnel)
3039 : {
3040 : /* commit */
3041 0 : tunnel->t_af = AF_UNSPEC;
3042 :
3043 0 : return (0);
3044 : }
3045 :
3046 : static int
3047 0 : gre_set_vnetid(struct gre_tunnel *tunnel, struct ifreq *ifr)
3048 : {
3049 : uint32_t key;
3050 : uint32_t min = GRE_KEY_MIN;
3051 : uint32_t max = GRE_KEY_MAX;
3052 : unsigned int shift = GRE_KEY_SHIFT;
3053 : uint32_t mask = GRE_KEY_MASK;
3054 :
3055 0 : if (tunnel->t_key_mask == GRE_KEY_ENTROPY) {
3056 : min = GRE_KEY_ENTROPY_MIN;
3057 : max = GRE_KEY_ENTROPY_MAX;
3058 : shift = GRE_KEY_ENTROPY_SHIFT;
3059 : mask = GRE_KEY_ENTROPY;
3060 0 : }
3061 :
3062 0 : if (ifr->ifr_vnetid < min || ifr->ifr_vnetid > max)
3063 0 : return (EINVAL);
3064 :
3065 0 : key = htonl(ifr->ifr_vnetid << shift);
3066 :
3067 : /* commit */
3068 0 : tunnel->t_key_mask = mask;
3069 0 : tunnel->t_key = key;
3070 :
3071 0 : return (0);
3072 0 : }
3073 :
3074 : static int
3075 0 : gre_get_vnetid(struct gre_tunnel *tunnel, struct ifreq *ifr)
3076 : {
3077 : int shift;
3078 :
3079 0 : switch (tunnel->t_key_mask) {
3080 : case GRE_KEY_NONE:
3081 0 : return (EADDRNOTAVAIL);
3082 : case GRE_KEY_ENTROPY:
3083 : shift = GRE_KEY_ENTROPY_SHIFT;
3084 0 : break;
3085 : case GRE_KEY_MASK:
3086 : shift = GRE_KEY_SHIFT;
3087 0 : break;
3088 : }
3089 :
3090 0 : ifr->ifr_vnetid = ntohl(tunnel->t_key) >> shift;
3091 :
3092 0 : return (0);
3093 0 : }
3094 :
3095 : static int
3096 0 : gre_del_vnetid(struct gre_tunnel *tunnel)
3097 : {
3098 0 : tunnel->t_key_mask = GRE_KEY_NONE;
3099 :
3100 0 : return (0);
3101 : }
3102 :
3103 : static int
3104 0 : gre_set_vnetflowid(struct gre_tunnel *tunnel, struct ifreq *ifr)
3105 : {
3106 : uint32_t mask, key;
3107 :
3108 0 : if (tunnel->t_key_mask == GRE_KEY_NONE)
3109 0 : return (EADDRNOTAVAIL);
3110 :
3111 0 : mask = ifr->ifr_vnetid ? GRE_KEY_ENTROPY : GRE_KEY_MASK;
3112 0 : if (tunnel->t_key_mask == mask) {
3113 : /* nop */
3114 0 : return (0);
3115 : }
3116 :
3117 0 : key = ntohl(tunnel->t_key);
3118 0 : if (mask == GRE_KEY_ENTROPY) {
3119 0 : if (key > GRE_KEY_ENTROPY_MAX)
3120 0 : return (ERANGE);
3121 :
3122 0 : key = htonl(key << GRE_KEY_ENTROPY_SHIFT);
3123 0 : } else
3124 0 : key = htonl(key >> GRE_KEY_ENTROPY_SHIFT);
3125 :
3126 : /* commit */
3127 0 : tunnel->t_key_mask = mask;
3128 0 : tunnel->t_key = key;
3129 :
3130 0 : return (0);
3131 0 : }
3132 :
3133 : static int
3134 0 : gre_get_vnetflowid(struct gre_tunnel *tunnel, struct ifreq *ifr)
3135 : {
3136 0 : if (tunnel->t_key_mask == GRE_KEY_NONE)
3137 0 : return (EADDRNOTAVAIL);
3138 :
3139 0 : ifr->ifr_vnetid = tunnel->t_key_mask == GRE_KEY_ENTROPY;
3140 :
3141 0 : return (0);
3142 0 : }
3143 :
3144 : static int
3145 0 : mgre_up(struct mgre_softc *sc)
3146 : {
3147 : unsigned int hlen;
3148 :
3149 0 : switch (sc->sc_tunnel.t_af) {
3150 : case AF_UNSPEC:
3151 0 : return (EDESTADDRREQ);
3152 : case AF_INET:
3153 : hlen = sizeof(struct ip);
3154 0 : break;
3155 : #ifdef INET6
3156 : case AF_INET6:
3157 : hlen = sizeof(struct ip6_hdr);
3158 0 : break;
3159 : #endif /* INET6 */
3160 : }
3161 :
3162 0 : hlen += sizeof(struct gre_header);
3163 0 : if (sc->sc_tunnel.t_key_mask != GRE_KEY_NONE)
3164 0 : hlen += sizeof(struct gre_h_key);
3165 :
3166 0 : NET_ASSERT_LOCKED();
3167 :
3168 0 : if (RBT_INSERT(mgre_tree, &mgre_tree, sc) != NULL)
3169 0 : return (EADDRINUSE);
3170 :
3171 0 : sc->sc_if.if_hdrlen = hlen;
3172 0 : SET(sc->sc_if.if_flags, IFF_RUNNING);
3173 :
3174 0 : return (0);
3175 0 : }
3176 :
3177 : static int
3178 0 : mgre_down(struct mgre_softc *sc)
3179 : {
3180 0 : NET_ASSERT_LOCKED();
3181 :
3182 0 : CLR(sc->sc_if.if_flags, IFF_RUNNING);
3183 0 : sc->sc_if.if_hdrlen = GRE_HDRLEN; /* symmetry */
3184 :
3185 0 : RBT_REMOVE(mgre_tree, &mgre_tree, sc);
3186 :
3187 : /* barrier? */
3188 :
3189 0 : return (0);
3190 : }
3191 :
3192 : static int
3193 0 : egre_up(struct egre_softc *sc)
3194 : {
3195 0 : if (sc->sc_tunnel.t_af == AF_UNSPEC)
3196 0 : return (EDESTADDRREQ);
3197 :
3198 0 : NET_ASSERT_LOCKED();
3199 :
3200 0 : if (RBT_INSERT(egre_tree, &egre_tree, sc) != NULL)
3201 0 : return (EADDRINUSE);
3202 :
3203 0 : SET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
3204 :
3205 0 : return (0);
3206 0 : }
3207 :
3208 : static int
3209 0 : egre_down(struct egre_softc *sc)
3210 : {
3211 0 : NET_ASSERT_LOCKED();
3212 :
3213 0 : CLR(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
3214 :
3215 0 : RBT_REMOVE(egre_tree, &egre_tree, sc);
3216 :
3217 : /* barrier? */
3218 :
3219 0 : return (0);
3220 : }
3221 :
3222 : static int
3223 0 : egre_media_change(struct ifnet *ifp)
3224 : {
3225 0 : return (ENOTTY);
3226 : }
3227 :
3228 : static void
3229 0 : egre_media_status(struct ifnet *ifp, struct ifmediareq *imr)
3230 : {
3231 0 : imr->ifm_active = IFM_ETHER | IFM_AUTO;
3232 0 : imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
3233 0 : }
3234 :
3235 : static int
3236 0 : nvgre_up(struct nvgre_softc *sc)
3237 : {
3238 0 : struct gre_tunnel *tunnel = &sc->sc_tunnel;
3239 : struct ifnet *ifp0;
3240 : void *inm;
3241 0 : int error;
3242 :
3243 0 : if (tunnel->t_af == AF_UNSPEC)
3244 0 : return (EDESTADDRREQ);
3245 :
3246 0 : ifp0 = if_get(sc->sc_ifp0);
3247 0 : if (ifp0 == NULL)
3248 0 : return (ENXIO);
3249 0 : if (!ISSET(ifp0->if_flags, IFF_MULTICAST)) {
3250 0 : error = ENODEV;
3251 0 : goto put;
3252 : }
3253 :
3254 0 : NET_ASSERT_LOCKED();
3255 :
3256 0 : if (RBT_INSERT(nvgre_mcast_tree, &nvgre_mcast_tree, sc) != NULL) {
3257 0 : error = EADDRINUSE;
3258 0 : goto put;
3259 : }
3260 0 : if (RBT_INSERT(nvgre_ucast_tree, &nvgre_ucast_tree, sc) != NULL) {
3261 0 : error = EADDRINUSE;
3262 0 : goto remove_mcast;
3263 : }
3264 :
3265 0 : switch (tunnel->t_af) {
3266 : case AF_INET:
3267 0 : inm = in_addmulti(&tunnel->t_dst4, ifp0);
3268 0 : if (inm == NULL) {
3269 0 : error = ECONNABORTED;
3270 0 : goto remove_ucast;
3271 : }
3272 : break;
3273 : #ifdef INET6
3274 : case AF_INET6:
3275 0 : inm = in6_addmulti(&tunnel->t_dst6, ifp0, &error);
3276 0 : if (inm == NULL) {
3277 : /* error is already set */
3278 : goto remove_ucast;
3279 : }
3280 : break;
3281 : #endif /* INET6 */
3282 : default:
3283 0 : unhandled_af(tunnel->t_af);
3284 : }
3285 :
3286 0 : sc->sc_lhcookie = hook_establish(ifp0->if_linkstatehooks, 0,
3287 0 : nvgre_link_change, sc);
3288 0 : if (sc->sc_lhcookie == NULL) {
3289 0 : error = ENOMEM;
3290 0 : goto delmulti;
3291 : }
3292 :
3293 0 : sc->sc_dhcookie = hook_establish(ifp0->if_detachhooks, 0,
3294 : nvgre_detach, sc);
3295 0 : if (sc->sc_dhcookie == NULL) {
3296 0 : error = ENOMEM;
3297 : goto dislh;
3298 : }
3299 :
3300 0 : if_put(ifp0);
3301 :
3302 0 : sc->sc_inm = inm;
3303 0 : SET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
3304 :
3305 0 : timeout_add_sec(&sc->sc_ether_age, NVGRE_AGE_TMO);
3306 :
3307 0 : return (0);
3308 :
3309 : dislh:
3310 0 : hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lhcookie);
3311 : delmulti:
3312 0 : switch (tunnel->t_af) {
3313 : case AF_INET:
3314 0 : in_delmulti(inm);
3315 0 : break;
3316 : #ifdef INET6
3317 : case AF_INET6:
3318 0 : in6_delmulti(inm);
3319 0 : break;
3320 : #endif
3321 : }
3322 : remove_ucast:
3323 0 : RBT_REMOVE(nvgre_ucast_tree, &nvgre_ucast_tree, sc);
3324 : remove_mcast:
3325 0 : RBT_REMOVE(nvgre_mcast_tree, &nvgre_mcast_tree, sc);
3326 : put:
3327 0 : if_put(ifp0);
3328 0 : return (error);
3329 0 : }
3330 :
3331 : static int
3332 0 : nvgre_down(struct nvgre_softc *sc)
3333 : {
3334 0 : struct gre_tunnel *tunnel = &sc->sc_tunnel;
3335 0 : struct ifnet *ifp = &sc->sc_ac.ac_if;
3336 0 : struct taskq *softnet = net_tq(ifp->if_index);
3337 : struct ifnet *ifp0;
3338 :
3339 0 : NET_ASSERT_LOCKED();
3340 :
3341 0 : CLR(ifp->if_flags, IFF_RUNNING);
3342 :
3343 0 : NET_UNLOCK();
3344 0 : if (!timeout_del(&sc->sc_ether_age))
3345 0 : timeout_barrier(&sc->sc_ether_age);
3346 0 : ifq_barrier(&ifp->if_snd);
3347 0 : if (!task_del(softnet, &sc->sc_send_task))
3348 0 : taskq_barrier(softnet);
3349 0 : NET_LOCK();
3350 :
3351 0 : mq_purge(&sc->sc_send_list);
3352 :
3353 0 : ifp0 = if_get(sc->sc_ifp0);
3354 0 : if (ifp0 != NULL) {
3355 0 : hook_disestablish(ifp0->if_detachhooks, sc->sc_dhcookie);
3356 0 : hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lhcookie);
3357 0 : }
3358 0 : if_put(ifp0);
3359 :
3360 0 : switch (tunnel->t_af) {
3361 : case AF_INET:
3362 0 : in_delmulti(sc->sc_inm);
3363 0 : break;
3364 :
3365 : #ifdef INET6
3366 : case AF_INET6:
3367 0 : in6_delmulti(sc->sc_inm);
3368 0 : break;
3369 : #endif
3370 : }
3371 :
3372 0 : RBT_REMOVE(nvgre_ucast_tree, &nvgre_ucast_tree, sc);
3373 0 : RBT_REMOVE(nvgre_mcast_tree, &nvgre_mcast_tree, sc);
3374 :
3375 0 : return (0);
3376 : }
3377 :
3378 : static void
3379 0 : nvgre_link_change(void *arg)
3380 : {
3381 : /* nop */
3382 0 : }
3383 :
3384 : static void
3385 0 : nvgre_detach(void *arg)
3386 : {
3387 0 : struct nvgre_softc *sc = arg;
3388 0 : struct ifnet *ifp = &sc->sc_ac.ac_if;
3389 :
3390 0 : if (ISSET(ifp->if_flags, IFF_RUNNING)) {
3391 0 : nvgre_down(sc);
3392 0 : if_down(ifp);
3393 0 : }
3394 :
3395 0 : sc->sc_ifp0 = 0;
3396 0 : }
3397 :
3398 : static int
3399 0 : nvgre_set_parent(struct nvgre_softc *sc, const char *parent)
3400 : {
3401 : struct ifnet *ifp0;
3402 :
3403 0 : ifp0 = ifunit(parent); /* doesn't need an if_put */
3404 0 : if (ifp0 == NULL)
3405 0 : return (EINVAL);
3406 :
3407 0 : if (!ISSET(ifp0->if_flags, IFF_MULTICAST))
3408 0 : return (EPROTONOSUPPORT);
3409 :
3410 : /* commit */
3411 0 : sc->sc_ifp0 = ifp0->if_index;
3412 :
3413 0 : return (0);
3414 0 : }
3415 :
3416 : static void
3417 0 : nvgre_age(void *arg)
3418 : {
3419 0 : struct nvgre_softc *sc = arg;
3420 : struct nvgre_entry *nv, *nnv;
3421 0 : int tmo = sc->sc_ether_tmo * 2;
3422 : int diff;
3423 :
3424 0 : if (!ISSET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING))
3425 0 : return;
3426 :
3427 0 : rw_enter_write(&sc->sc_ether_lock); /* XXX */
3428 0 : RBT_FOREACH_SAFE(nv, nvgre_map, &sc->sc_ether_map, nnv) {
3429 0 : if (nv->nv_type != NVGRE_ENTRY_DYNAMIC)
3430 : continue;
3431 :
3432 0 : diff = ticks - nv->nv_age;
3433 0 : if (diff < tmo)
3434 : continue;
3435 :
3436 0 : sc->sc_ether_num--;
3437 0 : RBT_REMOVE(nvgre_map, &sc->sc_ether_map, nv);
3438 0 : if (refcnt_rele(&nv->nv_refs))
3439 0 : pool_put(&nvgre_pool, nv);
3440 : }
3441 0 : rw_exit_write(&sc->sc_ether_lock);
3442 :
3443 0 : timeout_add_sec(&sc->sc_ether_age, NVGRE_AGE_TMO);
3444 0 : }
3445 :
3446 : static inline int
3447 0 : nvgre_entry_valid(struct nvgre_softc *sc, const struct nvgre_entry *nv)
3448 : {
3449 : int diff;
3450 :
3451 0 : if (nv == NULL)
3452 0 : return (0);
3453 :
3454 0 : if (nv->nv_type == NVGRE_ENTRY_STATIC)
3455 0 : return (1);
3456 :
3457 0 : diff = ticks - nv->nv_age;
3458 0 : if (diff < sc->sc_ether_tmo)
3459 0 : return (1);
3460 :
3461 0 : return (0);
3462 0 : }
3463 :
3464 : static void
3465 0 : nvgre_start(struct ifnet *ifp)
3466 : {
3467 0 : struct nvgre_softc *sc = ifp->if_softc;
3468 0 : const struct gre_tunnel *tunnel = &sc->sc_tunnel;
3469 0 : union gre_addr gateway;
3470 0 : struct nvgre_entry *nv, key;
3471 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
3472 : struct ether_header *eh;
3473 : struct mbuf *m, *m0;
3474 : #if NBPFILTER > 0
3475 : caddr_t if_bpf;
3476 : #endif
3477 :
3478 0 : if (!gre_allow) {
3479 0 : ifq_purge(&ifp->if_snd);
3480 0 : return;
3481 : }
3482 :
3483 0 : while ((m0 = ifq_dequeue(&ifp->if_snd)) != NULL) {
3484 : #if NBPFILTER > 0
3485 0 : if_bpf = ifp->if_bpf;
3486 0 : if (if_bpf)
3487 0 : bpf_mtap_ether(if_bpf, m0, BPF_DIRECTION_OUT);
3488 : #endif
3489 :
3490 0 : eh = mtod(m0, struct ether_header *);
3491 0 : if (ether_isbcast(eh->ether_dhost))
3492 0 : gateway = tunnel->t_dst;
3493 : else {
3494 0 : memcpy(&key.nv_dst, eh->ether_dhost,
3495 : sizeof(key.nv_dst));
3496 :
3497 0 : rw_enter_read(&sc->sc_ether_lock);
3498 0 : nv = RBT_FIND(nvgre_map, &sc->sc_ether_map, &key);
3499 0 : if (nvgre_entry_valid(sc, nv))
3500 0 : gateway = nv->nv_gateway;
3501 : else {
3502 : /* "flood" to unknown hosts */
3503 0 : gateway = tunnel->t_dst;
3504 : }
3505 0 : rw_exit_read(&sc->sc_ether_lock);
3506 : }
3507 :
3508 0 : m = m_gethdr(M_DONTWAIT, m0->m_type);
3509 0 : if (m == NULL) {
3510 0 : m_freem(m0);
3511 0 : continue;
3512 : }
3513 :
3514 0 : M_MOVE_PKTHDR(m, m0);
3515 0 : m->m_next = m0;
3516 :
3517 0 : MH_ALIGN(m, 0);
3518 0 : m->m_len = 0;
3519 :
3520 0 : m = gre_encap_dst(tunnel, &gateway, m,
3521 0 : htons(ETHERTYPE_TRANSETHER), tunnel->t_ttl, 0);
3522 0 : if (m == NULL)
3523 0 : continue;
3524 :
3525 0 : m->m_flags &= ~(M_BCAST|M_MCAST);
3526 0 : m->m_pkthdr.ph_rtableid = tunnel->t_rtableid;
3527 :
3528 : #if NPF > 0
3529 0 : pf_pkt_addr_changed(m);
3530 : #endif
3531 :
3532 0 : ml_enqueue(&ml, m);
3533 : }
3534 :
3535 0 : if (!ml_empty(&ml)) {
3536 0 : if (mq_enlist(&sc->sc_send_list, &ml) == 0)
3537 0 : task_add(net_tq(ifp->if_index), &sc->sc_send_task);
3538 : /* else set OACTIVE? */
3539 : }
3540 0 : }
3541 :
3542 : static uint64_t
3543 0 : nvgre_send4(struct nvgre_softc *sc, struct mbuf_list *ml)
3544 : {
3545 0 : struct ip_moptions imo;
3546 : struct mbuf *m;
3547 : uint64_t oerrors = 0;
3548 :
3549 0 : imo.imo_ifidx = sc->sc_ifp0;
3550 0 : imo.imo_ttl = sc->sc_tunnel.t_ttl;
3551 0 : imo.imo_loop = 0;
3552 :
3553 0 : NET_RLOCK();
3554 0 : while ((m = ml_dequeue(ml)) != NULL) {
3555 0 : if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &imo, NULL, 0) != 0)
3556 0 : oerrors++;
3557 : }
3558 0 : NET_RUNLOCK();
3559 :
3560 0 : return (oerrors);
3561 0 : }
3562 :
3563 : #ifdef INET6
3564 : static uint64_t
3565 0 : nvgre_send6(struct nvgre_softc *sc, struct mbuf_list *ml)
3566 : {
3567 0 : struct ip6_moptions im6o;
3568 : struct mbuf *m;
3569 : uint64_t oerrors = 0;
3570 :
3571 0 : im6o.im6o_ifidx = sc->sc_ifp0;
3572 0 : im6o.im6o_hlim = sc->sc_tunnel.t_ttl;
3573 0 : im6o.im6o_loop = 0;
3574 :
3575 0 : NET_RLOCK();
3576 0 : while ((m = ml_dequeue(ml)) != NULL) {
3577 0 : if (ip6_output(m, NULL, NULL, 0, &im6o, NULL) != 0)
3578 0 : oerrors++;
3579 : }
3580 0 : NET_RUNLOCK();
3581 :
3582 0 : return (oerrors);
3583 0 : }
3584 : #endif /* INET6 */
3585 :
3586 : static void
3587 0 : nvgre_send(void *arg)
3588 : {
3589 0 : struct nvgre_softc *sc = arg;
3590 0 : struct ifnet *ifp = &sc->sc_ac.ac_if;
3591 0 : sa_family_t af = sc->sc_tunnel.t_af;
3592 0 : struct mbuf_list ml;
3593 : uint64_t oerrors;
3594 :
3595 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
3596 0 : return;
3597 :
3598 0 : mq_delist(&sc->sc_send_list, &ml);
3599 0 : if (ml_empty(&ml))
3600 0 : return;
3601 :
3602 0 : switch (af) {
3603 : case AF_INET:
3604 0 : oerrors = nvgre_send4(sc, &ml);
3605 0 : break;
3606 : #ifdef INET6
3607 : case AF_INET6:
3608 0 : oerrors = nvgre_send6(sc, &ml);
3609 0 : break;
3610 : #endif
3611 : default:
3612 0 : unhandled_af(af);
3613 : /* NOTREACHED */
3614 : }
3615 :
3616 0 : ifp->if_oerrors += oerrors; /* XXX should be ifq_oerrors */
3617 0 : }
3618 :
3619 : static int
3620 0 : eoip_up(struct eoip_softc *sc)
3621 : {
3622 0 : if (sc->sc_tunnel.t_af == AF_UNSPEC)
3623 0 : return (EDESTADDRREQ);
3624 :
3625 0 : NET_ASSERT_LOCKED();
3626 :
3627 0 : if (RBT_INSERT(eoip_tree, &eoip_tree, sc) != NULL)
3628 0 : return (EADDRINUSE);
3629 :
3630 0 : SET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
3631 :
3632 0 : if (sc->sc_ka_state != GRE_KA_NONE) {
3633 0 : sc->sc_ka_holdmax = sc->sc_ka_count;
3634 0 : eoip_keepalive_send(sc);
3635 0 : }
3636 :
3637 0 : return (0);
3638 0 : }
3639 :
3640 : static int
3641 0 : eoip_down(struct eoip_softc *sc)
3642 : {
3643 0 : NET_ASSERT_LOCKED();
3644 0 : CLR(sc->sc_ac.ac_if.if_flags, IFF_RUNNING);
3645 :
3646 0 : if (sc->sc_ka_state != GRE_KA_NONE) {
3647 0 : if (!timeout_del(&sc->sc_ka_hold))
3648 0 : timeout_barrier(&sc->sc_ka_hold);
3649 0 : if (!timeout_del(&sc->sc_ka_send))
3650 0 : timeout_barrier(&sc->sc_ka_send);
3651 :
3652 0 : sc->sc_ka_state = GRE_KA_DOWN;
3653 0 : gre_link_state(&sc->sc_ac.ac_if, sc->sc_ka_state);
3654 0 : }
3655 :
3656 0 : RBT_REMOVE(eoip_tree, &eoip_tree, sc);
3657 :
3658 0 : return (0);
3659 : }
3660 :
3661 : static void
3662 0 : eoip_start(struct ifnet *ifp)
3663 : {
3664 0 : struct eoip_softc *sc = ifp->if_softc;
3665 : struct mbuf *m0, *m;
3666 : #if NBPFILTER > 0
3667 : caddr_t if_bpf;
3668 : #endif
3669 :
3670 0 : if (!gre_allow) {
3671 0 : ifq_purge(&ifp->if_snd);
3672 0 : return;
3673 : }
3674 :
3675 0 : while ((m0 = ifq_dequeue(&ifp->if_snd)) != NULL) {
3676 : #if NBPFILTER > 0
3677 0 : if_bpf = ifp->if_bpf;
3678 0 : if (if_bpf)
3679 0 : bpf_mtap_ether(if_bpf, m0, BPF_DIRECTION_OUT);
3680 : #endif
3681 :
3682 0 : m = m_gethdr(M_DONTWAIT, m0->m_type);
3683 0 : if (m == NULL) {
3684 0 : m_freem(m0);
3685 0 : continue;
3686 : }
3687 :
3688 0 : M_MOVE_PKTHDR(m, m0);
3689 0 : m->m_next = m0;
3690 :
3691 0 : MH_ALIGN(m, 0);
3692 0 : m->m_len = 0;
3693 :
3694 0 : m = eoip_encap(sc, m, 0);
3695 0 : if (m == NULL || gre_ip_output(&sc->sc_tunnel, m) != 0) {
3696 0 : ifp->if_oerrors++;
3697 0 : continue;
3698 : }
3699 : }
3700 0 : }
3701 :
3702 : static struct mbuf *
3703 0 : eoip_encap(struct eoip_softc *sc, struct mbuf *m, uint8_t tos)
3704 : {
3705 : struct gre_header *gh;
3706 : struct gre_h_key_eoip *eoiph;
3707 0 : int len = m->m_pkthdr.len;
3708 :
3709 0 : m = m_prepend(m, sizeof(*gh) + sizeof(*eoiph), M_DONTWAIT);
3710 0 : if (m == NULL)
3711 0 : return (NULL);
3712 :
3713 0 : gh = mtod(m, struct gre_header *);
3714 0 : gh->gre_flags = htons(GRE_VERS_1 | GRE_KP);
3715 0 : gh->gre_proto = htons(GRE_EOIP);
3716 :
3717 0 : eoiph = (struct gre_h_key_eoip *)(gh + 1);
3718 0 : htobem16(&eoiph->eoip_len, len);
3719 0 : eoiph->eoip_tunnel_id = sc->sc_tunnel_id;
3720 :
3721 0 : return (gre_encap_ip(&sc->sc_tunnel, m, sc->sc_tunnel.t_ttl, tos));
3722 0 : }
3723 :
3724 : static void
3725 0 : eoip_keepalive_send(void *arg)
3726 : {
3727 0 : struct eoip_softc *sc = arg;
3728 : struct mbuf *m;
3729 : int linkhdr;
3730 :
3731 0 : if (!ISSET(sc->sc_ac.ac_if.if_flags, IFF_RUNNING))
3732 0 : return;
3733 :
3734 : /* this is really conservative */
3735 : #ifdef INET6
3736 0 : linkhdr = max_linkhdr + MAX(sizeof(struct ip), sizeof(struct ip6_hdr)) +
3737 0 : sizeof(struct gre_header) + sizeof(struct gre_h_key_eoip);
3738 : #else
3739 : linkhdr = max_linkhdr + sizeof(struct ip) +
3740 : sizeof(struct gre_header) + sizeof(struct gre_h_key_eoip);
3741 : #endif
3742 0 : MGETHDR(m, M_DONTWAIT, MT_DATA);
3743 0 : if (m == NULL)
3744 0 : return;
3745 :
3746 0 : if (linkhdr > MHLEN) {
3747 0 : MCLGETI(m, M_DONTWAIT, NULL, linkhdr);
3748 0 : if (!ISSET(m->m_flags, M_EXT)) {
3749 0 : m_freem(m);
3750 0 : return;
3751 : }
3752 : }
3753 :
3754 0 : m->m_pkthdr.len = m->m_len = linkhdr;
3755 0 : m_adj(m, linkhdr);
3756 :
3757 0 : m = eoip_encap(sc, m, IPTOS_PREC_INTERNETCONTROL);
3758 0 : if (m == NULL)
3759 0 : return;
3760 :
3761 0 : gre_ip_output(&sc->sc_tunnel, m);
3762 :
3763 0 : timeout_add_sec(&sc->sc_ka_send, sc->sc_ka_timeo);
3764 0 : }
3765 :
3766 : static void
3767 0 : eoip_keepalive_hold(void *arg)
3768 : {
3769 0 : struct eoip_softc *sc = arg;
3770 0 : struct ifnet *ifp = &sc->sc_ac.ac_if;
3771 :
3772 0 : if (!ISSET(ifp->if_flags, IFF_RUNNING))
3773 0 : return;
3774 :
3775 0 : NET_LOCK();
3776 0 : sc->sc_ka_state = GRE_KA_DOWN;
3777 0 : gre_link_state(ifp, sc->sc_ka_state);
3778 0 : NET_UNLOCK();
3779 0 : }
3780 :
3781 : static void
3782 0 : eoip_keepalive_recv(struct eoip_softc *sc)
3783 : {
3784 0 : switch (sc->sc_ka_state) {
3785 : case GRE_KA_NONE:
3786 : return;
3787 : case GRE_KA_DOWN:
3788 0 : sc->sc_ka_state = GRE_KA_HOLD;
3789 0 : sc->sc_ka_holdcnt = sc->sc_ka_holdmax;
3790 0 : sc->sc_ka_holdmax = MIN(sc->sc_ka_holdmax * 2,
3791 : 16 * sc->sc_ka_count);
3792 0 : break;
3793 : case GRE_KA_HOLD:
3794 0 : if (--sc->sc_ka_holdcnt > 0)
3795 : break;
3796 :
3797 0 : sc->sc_ka_state = GRE_KA_UP;
3798 0 : gre_link_state(&sc->sc_ac.ac_if, sc->sc_ka_state);
3799 0 : break;
3800 :
3801 : case GRE_KA_UP:
3802 0 : sc->sc_ka_holdmax--;
3803 0 : sc->sc_ka_holdmax = MAX(sc->sc_ka_holdmax, sc->sc_ka_count);
3804 0 : break;
3805 : }
3806 :
3807 0 : timeout_add_sec(&sc->sc_ka_hold, sc->sc_ka_timeo * sc->sc_ka_count);
3808 0 : }
3809 :
3810 : static struct mbuf *
3811 0 : eoip_input(struct gre_tunnel *key, struct mbuf *m,
3812 : const struct gre_header *gh, int iphlen)
3813 : {
3814 0 : struct mbuf_list ml = MBUF_LIST_INITIALIZER();
3815 : struct eoip_softc *sc;
3816 : struct gre_h_key_eoip *eoiph;
3817 : int hlen, len;
3818 : caddr_t buf;
3819 :
3820 0 : if (gh->gre_flags != htons(GRE_KP | GRE_VERS_1))
3821 : goto decline;
3822 :
3823 0 : hlen = iphlen + sizeof(*gh) + sizeof(*eoiph);
3824 0 : if (m->m_pkthdr.len < hlen)
3825 : goto decline;
3826 :
3827 0 : m = m_pullup(m, hlen);
3828 0 : if (m == NULL)
3829 0 : return (NULL);
3830 :
3831 0 : buf = mtod(m, caddr_t);
3832 0 : gh = (struct gre_header *)(buf + iphlen);
3833 0 : eoiph = (struct gre_h_key_eoip *)(gh + 1);
3834 :
3835 0 : key->t_key = eoiph->eoip_tunnel_id;
3836 :
3837 0 : NET_ASSERT_LOCKED();
3838 0 : sc = RBT_FIND(eoip_tree, &eoip_tree, (const struct eoip_softc *)key);
3839 0 : if (sc == NULL)
3840 : goto decline;
3841 :
3842 : /* it's ours now */
3843 0 : len = bemtoh16(&eoiph->eoip_len);
3844 0 : if (len == 0) {
3845 0 : eoip_keepalive_recv(sc);
3846 0 : goto drop;
3847 : }
3848 :
3849 0 : m = gre_ether_align(m, hlen);
3850 0 : if (m == NULL)
3851 0 : return (NULL);
3852 :
3853 0 : if (m->m_pkthdr.len < len)
3854 : goto drop;
3855 0 : if (m->m_pkthdr.len != len)
3856 0 : m_adj(m, len - m->m_pkthdr.len);
3857 :
3858 0 : m->m_flags &= ~(M_MCAST|M_BCAST);
3859 :
3860 : #if NPF > 0
3861 0 : pf_pkt_addr_changed(m);
3862 : #endif
3863 :
3864 0 : ml_enqueue(&ml, m);
3865 0 : if_input(&sc->sc_ac.ac_if, &ml);
3866 :
3867 0 : return (NULL);
3868 :
3869 : decline:
3870 0 : return (m);
3871 : drop:
3872 0 : m_freem(m);
3873 0 : return (NULL);
3874 0 : }
3875 :
3876 : int
3877 0 : gre_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
3878 : size_t newlen)
3879 : {
3880 : int error;
3881 :
3882 : /* All sysctl names at this level are terminal. */
3883 0 : if (namelen != 1)
3884 0 : return (ENOTDIR);
3885 :
3886 0 : switch (name[0]) {
3887 : case GRECTL_ALLOW:
3888 0 : NET_LOCK();
3889 0 : error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_allow);
3890 0 : NET_UNLOCK();
3891 0 : return (error);
3892 : case GRECTL_WCCP:
3893 0 : NET_LOCK();
3894 0 : error = sysctl_int(oldp, oldlenp, newp, newlen, &gre_wccp);
3895 0 : NET_UNLOCK();
3896 0 : return (error);
3897 : default:
3898 0 : return (ENOPROTOOPT);
3899 : }
3900 : /* NOTREACHED */
3901 0 : }
3902 :
3903 : static inline int
3904 0 : gre_ip_cmp(int af, const union gre_addr *a, const union gre_addr *b)
3905 : {
3906 0 : switch (af) {
3907 : #ifdef INET6
3908 : case AF_INET6:
3909 0 : return (memcmp(&a->in6, &b->in6, sizeof(a->in6)));
3910 : #endif /* INET6 */
3911 : case AF_INET:
3912 0 : return (memcmp(&a->in4, &b->in4, sizeof(a->in4)));
3913 : default:
3914 0 : panic("%s: unsupported af %d\n", __func__, af);
3915 : }
3916 :
3917 : return (0);
3918 0 : }
3919 :
3920 : static int
3921 0 : gre_cmp_src(const struct gre_tunnel *a, const struct gre_tunnel *b)
3922 : {
3923 : uint32_t ka, kb;
3924 : uint32_t mask;
3925 : int rv;
3926 :
3927 : /* is K set at all? */
3928 0 : ka = a->t_key_mask & GRE_KEY_ENTROPY;
3929 0 : kb = b->t_key_mask & GRE_KEY_ENTROPY;
3930 :
3931 : /* sort by whether K is set */
3932 0 : if (ka > kb)
3933 0 : return (1);
3934 0 : if (ka < kb)
3935 0 : return (-1);
3936 :
3937 : /* is K set on both? */
3938 0 : if (ka != GRE_KEY_NONE) {
3939 : /* get common prefix */
3940 0 : mask = a->t_key_mask & b->t_key_mask;
3941 :
3942 0 : ka = a->t_key & mask;
3943 0 : kb = b->t_key & mask;
3944 :
3945 : /* sort by common prefix */
3946 0 : if (ka > kb)
3947 0 : return (1);
3948 0 : if (ka < kb)
3949 0 : return (-1);
3950 : }
3951 :
3952 : /* sort by routing table */
3953 0 : if (a->t_rtableid > b->t_rtableid)
3954 0 : return (1);
3955 0 : if (a->t_rtableid < b->t_rtableid)
3956 0 : return (-1);
3957 :
3958 : /* sort by address */
3959 0 : if (a->t_af > b->t_af)
3960 0 : return (1);
3961 0 : if (a->t_af < b->t_af)
3962 0 : return (-1);
3963 :
3964 0 : rv = gre_ip_cmp(a->t_af, &a->t_src, &b->t_src);
3965 0 : if (rv != 0)
3966 0 : return (rv);
3967 :
3968 0 : return (0);
3969 0 : }
3970 :
3971 : static int
3972 0 : gre_cmp(const struct gre_tunnel *a, const struct gre_tunnel *b)
3973 : {
3974 : int rv;
3975 :
3976 0 : rv = gre_cmp_src(a, b);
3977 0 : if (rv != 0)
3978 0 : return (rv);
3979 :
3980 0 : return (gre_ip_cmp(a->t_af, &a->t_dst, &b->t_dst));
3981 0 : }
3982 :
3983 : static inline int
3984 0 : mgre_cmp(const struct mgre_softc *a, const struct mgre_softc *b)
3985 : {
3986 0 : return (gre_cmp_src(&a->sc_tunnel, &b->sc_tunnel));
3987 : }
3988 :
3989 0 : RBT_GENERATE(mgre_tree, mgre_softc, sc_entry, mgre_cmp);
3990 :
3991 : static inline int
3992 0 : egre_cmp(const struct egre_softc *a, const struct egre_softc *b)
3993 : {
3994 0 : return (gre_cmp(&a->sc_tunnel, &b->sc_tunnel));
3995 : }
3996 :
3997 0 : RBT_GENERATE(egre_tree, egre_softc, sc_entry, egre_cmp);
3998 :
3999 : static inline int
4000 0 : nvgre_entry_cmp(const struct nvgre_entry *a, const struct nvgre_entry *b)
4001 : {
4002 0 : return (memcmp(&a->nv_dst, &b->nv_dst, sizeof(a->nv_dst)));
4003 : }
4004 :
4005 0 : RBT_GENERATE(nvgre_map, nvgre_entry, nv_entry, nvgre_entry_cmp);
4006 :
4007 : static int
4008 0 : nvgre_cmp_tunnel(const struct gre_tunnel *a, const struct gre_tunnel *b)
4009 : {
4010 : uint32_t ka, kb;
4011 :
4012 0 : ka = a->t_key & GRE_KEY_ENTROPY;
4013 0 : kb = b->t_key & GRE_KEY_ENTROPY;
4014 :
4015 : /* sort by common prefix */
4016 0 : if (ka > kb)
4017 0 : return (1);
4018 0 : if (ka < kb)
4019 0 : return (-1);
4020 :
4021 : /* sort by routing table */
4022 0 : if (a->t_rtableid > b->t_rtableid)
4023 0 : return (1);
4024 0 : if (a->t_rtableid < b->t_rtableid)
4025 0 : return (-1);
4026 :
4027 : /* sort by address */
4028 0 : if (a->t_af > b->t_af)
4029 0 : return (1);
4030 0 : if (a->t_af < b->t_af)
4031 0 : return (-1);
4032 :
4033 0 : return (0);
4034 0 : }
4035 :
4036 : static inline int
4037 0 : nvgre_cmp_ucast(const struct nvgre_softc *na, const struct nvgre_softc *nb)
4038 : {
4039 0 : const struct gre_tunnel *a = &na->sc_tunnel;
4040 0 : const struct gre_tunnel *b = &nb->sc_tunnel;
4041 : int rv;
4042 :
4043 0 : rv = nvgre_cmp_tunnel(a, b);
4044 0 : if (rv != 0)
4045 0 : return (rv);
4046 :
4047 0 : rv = gre_ip_cmp(a->t_af, &a->t_src, &b->t_src);
4048 0 : if (rv != 0)
4049 0 : return (rv);
4050 :
4051 0 : return (0);
4052 0 : }
4053 :
4054 : static int
4055 0 : nvgre_cmp_mcast(const struct gre_tunnel *a, const union gre_addr *aa,
4056 : unsigned int if0idxa, const struct gre_tunnel *b,
4057 : const union gre_addr *ab,unsigned int if0idxb)
4058 : {
4059 : int rv;
4060 :
4061 0 : rv = nvgre_cmp_tunnel(a, b);
4062 0 : if (rv != 0)
4063 0 : return (rv);
4064 :
4065 0 : rv = gre_ip_cmp(a->t_af, aa, ab);
4066 0 : if (rv != 0)
4067 0 : return (rv);
4068 :
4069 0 : if (if0idxa > if0idxb)
4070 0 : return (1);
4071 0 : if (if0idxa < if0idxb)
4072 0 : return (-1);
4073 :
4074 0 : return (0);
4075 0 : }
4076 :
4077 : static inline int
4078 0 : nvgre_cmp_mcast_sc(const struct nvgre_softc *na, const struct nvgre_softc *nb)
4079 : {
4080 0 : const struct gre_tunnel *a = &na->sc_tunnel;
4081 0 : const struct gre_tunnel *b = &nb->sc_tunnel;
4082 :
4083 0 : return (nvgre_cmp_mcast(a, &a->t_dst, na->sc_ifp0,
4084 0 : b, &b->t_dst, nb->sc_ifp0));
4085 : }
4086 :
4087 0 : RBT_GENERATE(nvgre_ucast_tree, nvgre_softc, sc_uentry, nvgre_cmp_ucast);
4088 0 : RBT_GENERATE(nvgre_mcast_tree, nvgre_softc, sc_mentry, nvgre_cmp_mcast_sc);
4089 :
4090 : static inline int
4091 0 : eoip_cmp(const struct eoip_softc *ea, const struct eoip_softc *eb)
4092 : {
4093 0 : const struct gre_tunnel *a = &ea->sc_tunnel;
4094 0 : const struct gre_tunnel *b = &eb->sc_tunnel;
4095 : int rv;
4096 :
4097 0 : if (a->t_key > b->t_key)
4098 0 : return (1);
4099 0 : if (a->t_key < b->t_key)
4100 0 : return (-1);
4101 :
4102 : /* sort by routing table */
4103 0 : if (a->t_rtableid > b->t_rtableid)
4104 0 : return (1);
4105 0 : if (a->t_rtableid < b->t_rtableid)
4106 0 : return (-1);
4107 :
4108 : /* sort by address */
4109 0 : if (a->t_af > b->t_af)
4110 0 : return (1);
4111 0 : if (a->t_af < b->t_af)
4112 0 : return (-1);
4113 :
4114 0 : rv = gre_ip_cmp(a->t_af, &a->t_src, &b->t_src);
4115 0 : if (rv != 0)
4116 0 : return (rv);
4117 :
4118 0 : rv = gre_ip_cmp(a->t_af, &a->t_dst, &b->t_dst);
4119 0 : if (rv != 0)
4120 0 : return (rv);
4121 :
4122 0 : return (0);
4123 0 : }
4124 :
4125 0 : RBT_GENERATE(eoip_tree, eoip_softc, sc_entry, eoip_cmp);
|