Thu Dec 28 07:06:36 2017 UTC ()
Ensure the timer isn't running by using workqueue_wait


(ozaki-r)
diff -r1.146 -r1.147 src/sys/net/if_bridge.c
diff -r1.177 -r1.178 src/sys/net/if_spppsubr.c

cvs diff -r1.146 -r1.147 src/sys/net/if_bridge.c (switch to unified diff)

--- src/sys/net/if_bridge.c 2017/12/19 03:32:35 1.146
+++ src/sys/net/if_bridge.c 2017/12/28 07:06:36 1.147
@@ -1,2360 +1,2361 @@ @@ -1,2360 +1,2361 @@
1/* $NetBSD: if_bridge.c,v 1.146 2017/12/19 03:32:35 ozaki-r Exp $ */ 1/* $NetBSD: if_bridge.c,v 1.147 2017/12/28 07:06:36 ozaki-r Exp $ */
2 2
3/* 3/*
4 * Copyright 2001 Wasabi Systems, Inc. 4 * Copyright 2001 Wasabi Systems, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software 17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement: 18 * must display the following acknowledgement:
19 * This product includes software developed for the NetBSD Project by 19 * This product includes software developed for the NetBSD Project by
20 * Wasabi Systems, Inc. 20 * Wasabi Systems, Inc.
21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22 * or promote products derived from this software without specific prior 22 * or promote products derived from this software without specific prior
23 * written permission. 23 * written permission.
24 * 24 *
25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE. 35 * POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38/* 38/*
39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) 39 * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
40 * All rights reserved. 40 * All rights reserved.
41 * 41 *
42 * Redistribution and use in source and binary forms, with or without 42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions 43 * modification, are permitted provided that the following conditions
44 * are met: 44 * are met:
45 * 1. Redistributions of source code must retain the above copyright 45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer. 46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright 47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the 48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution. 49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software 50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement: 51 * must display the following acknowledgement:
52 * This product includes software developed by Jason L. Wright 52 * This product includes software developed by Jason L. Wright
53 * 4. The name of the author may not be used to endorse or promote products 53 * 4. The name of the author may not be used to endorse or promote products
54 * derived from this software without specific prior written permission. 54 * derived from this software without specific prior written permission.
55 * 55 *
56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 57 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 58 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
59 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 59 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 60 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 61 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 64 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 65 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
66 * POSSIBILITY OF SUCH DAMAGE. 66 * POSSIBILITY OF SUCH DAMAGE.
67 * 67 *
68 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp 68 * OpenBSD: if_bridge.c,v 1.60 2001/06/15 03:38:33 itojun Exp
69 */ 69 */
70 70
71/* 71/*
72 * Network interface bridge support. 72 * Network interface bridge support.
73 * 73 *
74 * TODO: 74 * TODO:
75 * 75 *
76 * - Currently only supports Ethernet-like interfaces (Ethernet, 76 * - Currently only supports Ethernet-like interfaces (Ethernet,
77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way 77 * 802.11, VLANs on Ethernet, etc.) Figure out a nice way
78 * to bridge other types of interfaces (FDDI-FDDI, and maybe 78 * to bridge other types of interfaces (FDDI-FDDI, and maybe
79 * consider heterogenous bridges). 79 * consider heterogenous bridges).
80 */ 80 */
81 81
82#include <sys/cdefs.h> 82#include <sys/cdefs.h>
83__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.146 2017/12/19 03:32:35 ozaki-r Exp $"); 83__KERNEL_RCSID(0, "$NetBSD: if_bridge.c,v 1.147 2017/12/28 07:06:36 ozaki-r Exp $");
84 84
85#ifdef _KERNEL_OPT 85#ifdef _KERNEL_OPT
86#include "opt_bridge_ipf.h" 86#include "opt_bridge_ipf.h"
87#include "opt_inet.h" 87#include "opt_inet.h"
88#include "opt_net_mpsafe.h" 88#include "opt_net_mpsafe.h"
89#endif /* _KERNEL_OPT */ 89#endif /* _KERNEL_OPT */
90 90
91#include <sys/param.h> 91#include <sys/param.h>
92#include <sys/kernel.h> 92#include <sys/kernel.h>
93#include <sys/mbuf.h> 93#include <sys/mbuf.h>
94#include <sys/queue.h> 94#include <sys/queue.h>
95#include <sys/socket.h> 95#include <sys/socket.h>
96#include <sys/socketvar.h> /* for softnet_lock */ 96#include <sys/socketvar.h> /* for softnet_lock */
97#include <sys/sockio.h> 97#include <sys/sockio.h>
98#include <sys/systm.h> 98#include <sys/systm.h>
99#include <sys/proc.h> 99#include <sys/proc.h>
100#include <sys/pool.h> 100#include <sys/pool.h>
101#include <sys/kauth.h> 101#include <sys/kauth.h>
102#include <sys/cpu.h> 102#include <sys/cpu.h>
103#include <sys/cprng.h> 103#include <sys/cprng.h>
104#include <sys/mutex.h> 104#include <sys/mutex.h>
105#include <sys/kmem.h> 105#include <sys/kmem.h>
106 106
107#include <net/bpf.h> 107#include <net/bpf.h>
108#include <net/if.h> 108#include <net/if.h>
109#include <net/if_dl.h> 109#include <net/if_dl.h>
110#include <net/if_types.h> 110#include <net/if_types.h>
111#include <net/if_llc.h> 111#include <net/if_llc.h>
112 112
113#include <net/if_ether.h> 113#include <net/if_ether.h>
114#include <net/if_bridgevar.h> 114#include <net/if_bridgevar.h>
115 115
116#if defined(BRIDGE_IPF) 116#if defined(BRIDGE_IPF)
117/* Used for bridge_ip[6]_checkbasic */ 117/* Used for bridge_ip[6]_checkbasic */
118#include <netinet/in.h> 118#include <netinet/in.h>
119#include <netinet/in_systm.h> 119#include <netinet/in_systm.h>
120#include <netinet/ip.h> 120#include <netinet/ip.h>
121#include <netinet/ip_var.h> 121#include <netinet/ip_var.h>
122#include <netinet/ip_private.h> /* XXX */ 122#include <netinet/ip_private.h> /* XXX */
123 123
124#include <netinet/ip6.h> 124#include <netinet/ip6.h>
125#include <netinet6/in6_var.h> 125#include <netinet6/in6_var.h>
126#include <netinet6/ip6_var.h> 126#include <netinet6/ip6_var.h>
127#include <netinet6/ip6_private.h> /* XXX */ 127#include <netinet6/ip6_private.h> /* XXX */
128#endif /* BRIDGE_IPF */ 128#endif /* BRIDGE_IPF */
129 129
130/* 130/*
131 * Size of the route hash table. Must be a power of two. 131 * Size of the route hash table. Must be a power of two.
132 */ 132 */
133#ifndef BRIDGE_RTHASH_SIZE 133#ifndef BRIDGE_RTHASH_SIZE
134#define BRIDGE_RTHASH_SIZE 1024 134#define BRIDGE_RTHASH_SIZE 1024
135#endif 135#endif
136 136
137#define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1) 137#define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1)
138 138
139#include "carp.h" 139#include "carp.h"
140#if NCARP > 0 140#if NCARP > 0
141#include <netinet/in.h> 141#include <netinet/in.h>
142#include <netinet/in_var.h> 142#include <netinet/in_var.h>
143#include <netinet/ip_carp.h> 143#include <netinet/ip_carp.h>
144#endif 144#endif
145 145
146#include "ioconf.h" 146#include "ioconf.h"
147 147
148__CTASSERT(sizeof(struct ifbifconf) == sizeof(struct ifbaconf)); 148__CTASSERT(sizeof(struct ifbifconf) == sizeof(struct ifbaconf));
149__CTASSERT(offsetof(struct ifbifconf, ifbic_len) == offsetof(struct ifbaconf, ifbac_len)); 149__CTASSERT(offsetof(struct ifbifconf, ifbic_len) == offsetof(struct ifbaconf, ifbac_len));
150__CTASSERT(offsetof(struct ifbifconf, ifbic_buf) == offsetof(struct ifbaconf, ifbac_buf)); 150__CTASSERT(offsetof(struct ifbifconf, ifbic_buf) == offsetof(struct ifbaconf, ifbac_buf));
151 151
152/* 152/*
153 * Maximum number of addresses to cache. 153 * Maximum number of addresses to cache.
154 */ 154 */
155#ifndef BRIDGE_RTABLE_MAX 155#ifndef BRIDGE_RTABLE_MAX
156#define BRIDGE_RTABLE_MAX 100 156#define BRIDGE_RTABLE_MAX 100
157#endif 157#endif
158 158
159/* 159/*
160 * Spanning tree defaults. 160 * Spanning tree defaults.
161 */ 161 */
162#define BSTP_DEFAULT_MAX_AGE (20 * 256) 162#define BSTP_DEFAULT_MAX_AGE (20 * 256)
163#define BSTP_DEFAULT_HELLO_TIME (2 * 256) 163#define BSTP_DEFAULT_HELLO_TIME (2 * 256)
164#define BSTP_DEFAULT_FORWARD_DELAY (15 * 256) 164#define BSTP_DEFAULT_FORWARD_DELAY (15 * 256)
165#define BSTP_DEFAULT_HOLD_TIME (1 * 256) 165#define BSTP_DEFAULT_HOLD_TIME (1 * 256)
166#define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000 166#define BSTP_DEFAULT_BRIDGE_PRIORITY 0x8000
167#define BSTP_DEFAULT_PORT_PRIORITY 0x80 167#define BSTP_DEFAULT_PORT_PRIORITY 0x80
168#define BSTP_DEFAULT_PATH_COST 55 168#define BSTP_DEFAULT_PATH_COST 55
169 169
170/* 170/*
171 * Timeout (in seconds) for entries learned dynamically. 171 * Timeout (in seconds) for entries learned dynamically.
172 */ 172 */
173#ifndef BRIDGE_RTABLE_TIMEOUT 173#ifndef BRIDGE_RTABLE_TIMEOUT
174#define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */ 174#define BRIDGE_RTABLE_TIMEOUT (20 * 60) /* same as ARP */
175#endif 175#endif
176 176
177/* 177/*
178 * Number of seconds between walks of the route list. 178 * Number of seconds between walks of the route list.
179 */ 179 */
180#ifndef BRIDGE_RTABLE_PRUNE_PERIOD 180#ifndef BRIDGE_RTABLE_PRUNE_PERIOD
181#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60) 181#define BRIDGE_RTABLE_PRUNE_PERIOD (5 * 60)
182#endif 182#endif
183 183
184#define BRIDGE_RT_LOCK(_sc) if ((_sc)->sc_rtlist_lock) \ 184#define BRIDGE_RT_LOCK(_sc) if ((_sc)->sc_rtlist_lock) \
185 mutex_enter((_sc)->sc_rtlist_lock) 185 mutex_enter((_sc)->sc_rtlist_lock)
186#define BRIDGE_RT_UNLOCK(_sc) if ((_sc)->sc_rtlist_lock) \ 186#define BRIDGE_RT_UNLOCK(_sc) if ((_sc)->sc_rtlist_lock) \
187 mutex_exit((_sc)->sc_rtlist_lock) 187 mutex_exit((_sc)->sc_rtlist_lock)
188#define BRIDGE_RT_LOCKED(_sc) (!(_sc)->sc_rtlist_lock || \ 188#define BRIDGE_RT_LOCKED(_sc) (!(_sc)->sc_rtlist_lock || \
189 mutex_owned((_sc)->sc_rtlist_lock)) 189 mutex_owned((_sc)->sc_rtlist_lock))
190 190
191#define BRIDGE_RT_PSZ_PERFORM(_sc) \ 191#define BRIDGE_RT_PSZ_PERFORM(_sc) \
192 if ((_sc)->sc_rtlist_psz != NULL) \ 192 if ((_sc)->sc_rtlist_psz != NULL) \
193 pserialize_perform((_sc)->sc_rtlist_psz); 193 pserialize_perform((_sc)->sc_rtlist_psz);
194 194
195#define BRIDGE_RT_RENTER(__s) do { __s = pserialize_read_enter(); } while (0) 195#define BRIDGE_RT_RENTER(__s) do { __s = pserialize_read_enter(); } while (0)
196#define BRIDGE_RT_REXIT(__s) do { pserialize_read_exit(__s); } while (0) 196#define BRIDGE_RT_REXIT(__s) do { pserialize_read_exit(__s); } while (0)
197 197
198 198
199#ifdef NET_MPSAFE 199#ifdef NET_MPSAFE
200#define DECLARE_LOCK_VARIABLE 200#define DECLARE_LOCK_VARIABLE
201#define ACQUIRE_GLOBAL_LOCKS() do { } while (0) 201#define ACQUIRE_GLOBAL_LOCKS() do { } while (0)
202#define RELEASE_GLOBAL_LOCKS() do { } while (0) 202#define RELEASE_GLOBAL_LOCKS() do { } while (0)
203#else 203#else
204#define DECLARE_LOCK_VARIABLE int __s 204#define DECLARE_LOCK_VARIABLE int __s
205#define ACQUIRE_GLOBAL_LOCKS() do { \ 205#define ACQUIRE_GLOBAL_LOCKS() do { \
206 KERNEL_LOCK(1, NULL); \ 206 KERNEL_LOCK(1, NULL); \
207 mutex_enter(softnet_lock); \ 207 mutex_enter(softnet_lock); \
208 __s = splsoftnet(); \ 208 __s = splsoftnet(); \
209 } while (0) 209 } while (0)
210#define RELEASE_GLOBAL_LOCKS() do { \ 210#define RELEASE_GLOBAL_LOCKS() do { \
211 splx(__s); \ 211 splx(__s); \
212 mutex_exit(softnet_lock); \ 212 mutex_exit(softnet_lock); \
213 KERNEL_UNLOCK_ONE(NULL); \ 213 KERNEL_UNLOCK_ONE(NULL); \
214 } while (0) 214 } while (0)
215#endif 215#endif
216 216
217struct psref_class *bridge_psref_class __read_mostly; 217struct psref_class *bridge_psref_class __read_mostly;
218 218
219int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD; 219int bridge_rtable_prune_period = BRIDGE_RTABLE_PRUNE_PERIOD;
220 220
221static struct pool bridge_rtnode_pool; 221static struct pool bridge_rtnode_pool;
222 222
223static int bridge_clone_create(struct if_clone *, int); 223static int bridge_clone_create(struct if_clone *, int);
224static int bridge_clone_destroy(struct ifnet *); 224static int bridge_clone_destroy(struct ifnet *);
225 225
226static int bridge_ioctl(struct ifnet *, u_long, void *); 226static int bridge_ioctl(struct ifnet *, u_long, void *);
227static int bridge_init(struct ifnet *); 227static int bridge_init(struct ifnet *);
228static void bridge_stop(struct ifnet *, int); 228static void bridge_stop(struct ifnet *, int);
229static void bridge_start(struct ifnet *); 229static void bridge_start(struct ifnet *);
230 230
231static void bridge_input(struct ifnet *, struct mbuf *); 231static void bridge_input(struct ifnet *, struct mbuf *);
232static void bridge_forward(struct bridge_softc *, struct mbuf *); 232static void bridge_forward(struct bridge_softc *, struct mbuf *);
233 233
234static void bridge_timer(void *); 234static void bridge_timer(void *);
235 235
236static void bridge_broadcast(struct bridge_softc *, struct ifnet *, 236static void bridge_broadcast(struct bridge_softc *, struct ifnet *,
237 struct mbuf *); 237 struct mbuf *);
238 238
239static int bridge_rtupdate(struct bridge_softc *, const uint8_t *, 239static int bridge_rtupdate(struct bridge_softc *, const uint8_t *,
240 struct ifnet *, int, uint8_t); 240 struct ifnet *, int, uint8_t);
241static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *); 241static struct ifnet *bridge_rtlookup(struct bridge_softc *, const uint8_t *);
242static void bridge_rttrim(struct bridge_softc *); 242static void bridge_rttrim(struct bridge_softc *);
243static void bridge_rtage(struct bridge_softc *); 243static void bridge_rtage(struct bridge_softc *);
244static void bridge_rtage_work(struct work *, void *); 244static void bridge_rtage_work(struct work *, void *);
245static void bridge_rtflush(struct bridge_softc *, int); 245static void bridge_rtflush(struct bridge_softc *, int);
246static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *); 246static int bridge_rtdaddr(struct bridge_softc *, const uint8_t *);
247static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp); 247static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp);
248 248
249static void bridge_rtable_init(struct bridge_softc *); 249static void bridge_rtable_init(struct bridge_softc *);
250static void bridge_rtable_fini(struct bridge_softc *); 250static void bridge_rtable_fini(struct bridge_softc *);
251 251
252static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *, 252static struct bridge_rtnode *bridge_rtnode_lookup(struct bridge_softc *,
253 const uint8_t *); 253 const uint8_t *);
254static int bridge_rtnode_insert(struct bridge_softc *, 254static int bridge_rtnode_insert(struct bridge_softc *,
255 struct bridge_rtnode *); 255 struct bridge_rtnode *);
256static void bridge_rtnode_remove(struct bridge_softc *, 256static void bridge_rtnode_remove(struct bridge_softc *,
257 struct bridge_rtnode *); 257 struct bridge_rtnode *);
258static void bridge_rtnode_destroy(struct bridge_rtnode *); 258static void bridge_rtnode_destroy(struct bridge_rtnode *);
259 259
260static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *, 260static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
261 const char *name, 261 const char *name,
262 struct psref *); 262 struct psref *);
263static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *, 263static struct bridge_iflist *bridge_lookup_member_if(struct bridge_softc *,
264 struct ifnet *ifp, 264 struct ifnet *ifp,
265 struct psref *); 265 struct psref *);
266static void bridge_release_member(struct bridge_softc *, struct bridge_iflist *, 266static void bridge_release_member(struct bridge_softc *, struct bridge_iflist *,
267 struct psref *); 267 struct psref *);
268static void bridge_delete_member(struct bridge_softc *, 268static void bridge_delete_member(struct bridge_softc *,
269 struct bridge_iflist *); 269 struct bridge_iflist *);
270static void bridge_acquire_member(struct bridge_softc *sc, 270static void bridge_acquire_member(struct bridge_softc *sc,
271 struct bridge_iflist *, 271 struct bridge_iflist *,
272 struct psref *); 272 struct psref *);
273 273
274static int bridge_ioctl_add(struct bridge_softc *, void *); 274static int bridge_ioctl_add(struct bridge_softc *, void *);
275static int bridge_ioctl_del(struct bridge_softc *, void *); 275static int bridge_ioctl_del(struct bridge_softc *, void *);
276static int bridge_ioctl_gifflags(struct bridge_softc *, void *); 276static int bridge_ioctl_gifflags(struct bridge_softc *, void *);
277static int bridge_ioctl_sifflags(struct bridge_softc *, void *); 277static int bridge_ioctl_sifflags(struct bridge_softc *, void *);
278static int bridge_ioctl_scache(struct bridge_softc *, void *); 278static int bridge_ioctl_scache(struct bridge_softc *, void *);
279static int bridge_ioctl_gcache(struct bridge_softc *, void *); 279static int bridge_ioctl_gcache(struct bridge_softc *, void *);
280static int bridge_ioctl_gifs(struct bridge_softc *, void *); 280static int bridge_ioctl_gifs(struct bridge_softc *, void *);
281static int bridge_ioctl_rts(struct bridge_softc *, void *); 281static int bridge_ioctl_rts(struct bridge_softc *, void *);
282static int bridge_ioctl_saddr(struct bridge_softc *, void *); 282static int bridge_ioctl_saddr(struct bridge_softc *, void *);
283static int bridge_ioctl_sto(struct bridge_softc *, void *); 283static int bridge_ioctl_sto(struct bridge_softc *, void *);
284static int bridge_ioctl_gto(struct bridge_softc *, void *); 284static int bridge_ioctl_gto(struct bridge_softc *, void *);
285static int bridge_ioctl_daddr(struct bridge_softc *, void *); 285static int bridge_ioctl_daddr(struct bridge_softc *, void *);
286static int bridge_ioctl_flush(struct bridge_softc *, void *); 286static int bridge_ioctl_flush(struct bridge_softc *, void *);
287static int bridge_ioctl_gpri(struct bridge_softc *, void *); 287static int bridge_ioctl_gpri(struct bridge_softc *, void *);
288static int bridge_ioctl_spri(struct bridge_softc *, void *); 288static int bridge_ioctl_spri(struct bridge_softc *, void *);
289static int bridge_ioctl_ght(struct bridge_softc *, void *); 289static int bridge_ioctl_ght(struct bridge_softc *, void *);
290static int bridge_ioctl_sht(struct bridge_softc *, void *); 290static int bridge_ioctl_sht(struct bridge_softc *, void *);
291static int bridge_ioctl_gfd(struct bridge_softc *, void *); 291static int bridge_ioctl_gfd(struct bridge_softc *, void *);
292static int bridge_ioctl_sfd(struct bridge_softc *, void *); 292static int bridge_ioctl_sfd(struct bridge_softc *, void *);
293static int bridge_ioctl_gma(struct bridge_softc *, void *); 293static int bridge_ioctl_gma(struct bridge_softc *, void *);
294static int bridge_ioctl_sma(struct bridge_softc *, void *); 294static int bridge_ioctl_sma(struct bridge_softc *, void *);
295static int bridge_ioctl_sifprio(struct bridge_softc *, void *); 295static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
296static int bridge_ioctl_sifcost(struct bridge_softc *, void *); 296static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
297#if defined(BRIDGE_IPF) 297#if defined(BRIDGE_IPF)
298static int bridge_ioctl_gfilt(struct bridge_softc *, void *); 298static int bridge_ioctl_gfilt(struct bridge_softc *, void *);
299static int bridge_ioctl_sfilt(struct bridge_softc *, void *); 299static int bridge_ioctl_sfilt(struct bridge_softc *, void *);
300static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int); 300static int bridge_ipf(void *, struct mbuf **, struct ifnet *, int);
301static int bridge_ip_checkbasic(struct mbuf **mp); 301static int bridge_ip_checkbasic(struct mbuf **mp);
302# ifdef INET6 302# ifdef INET6
303static int bridge_ip6_checkbasic(struct mbuf **mp); 303static int bridge_ip6_checkbasic(struct mbuf **mp);
304# endif /* INET6 */ 304# endif /* INET6 */
305#endif /* BRIDGE_IPF */ 305#endif /* BRIDGE_IPF */
306 306
307struct bridge_control { 307struct bridge_control {
308 int (*bc_func)(struct bridge_softc *, void *); 308 int (*bc_func)(struct bridge_softc *, void *);
309 int bc_argsize; 309 int bc_argsize;
310 int bc_flags; 310 int bc_flags;
311}; 311};
312 312
313#define BC_F_COPYIN 0x01 /* copy arguments in */ 313#define BC_F_COPYIN 0x01 /* copy arguments in */
314#define BC_F_COPYOUT 0x02 /* copy arguments out */ 314#define BC_F_COPYOUT 0x02 /* copy arguments out */
315#define BC_F_SUSER 0x04 /* do super-user check */ 315#define BC_F_SUSER 0x04 /* do super-user check */
316#define BC_F_XLATEIN 0x08 /* xlate arguments in */ 316#define BC_F_XLATEIN 0x08 /* xlate arguments in */
317#define BC_F_XLATEOUT 0x10 /* xlate arguments out */ 317#define BC_F_XLATEOUT 0x10 /* xlate arguments out */
318 318
319static const struct bridge_control bridge_control_table[] = { 319static const struct bridge_control bridge_control_table[] = {
320[BRDGADD] = {bridge_ioctl_add, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER}, 320[BRDGADD] = {bridge_ioctl_add, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
321[BRDGDEL] = {bridge_ioctl_del, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},  321[BRDGDEL] = {bridge_ioctl_del, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
322 322
323[BRDGGIFFLGS] = {bridge_ioctl_gifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_COPYOUT},  323[BRDGGIFFLGS] = {bridge_ioctl_gifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_COPYOUT},
324[BRDGSIFFLGS] = {bridge_ioctl_sifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},  324[BRDGSIFFLGS] = {bridge_ioctl_sifflags, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
325 325
326[BRDGSCACHE] = {bridge_ioctl_scache, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  326[BRDGSCACHE] = {bridge_ioctl_scache, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
327[BRDGGCACHE] = {bridge_ioctl_gcache, sizeof(struct ifbrparam), BC_F_COPYOUT},  327[BRDGGCACHE] = {bridge_ioctl_gcache, sizeof(struct ifbrparam), BC_F_COPYOUT},
328 328
329[OBRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_COPYIN|BC_F_COPYOUT},  329[OBRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_COPYIN|BC_F_COPYOUT},
330[OBRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_COPYIN|BC_F_COPYOUT},  330[OBRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_COPYIN|BC_F_COPYOUT},
331 331
332[BRDGSADDR] = {bridge_ioctl_saddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},  332[BRDGSADDR] = {bridge_ioctl_saddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
333 333
334[BRDGSTO] = {bridge_ioctl_sto, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  334[BRDGSTO] = {bridge_ioctl_sto, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
335[BRDGGTO] = {bridge_ioctl_gto, sizeof(struct ifbrparam), BC_F_COPYOUT},  335[BRDGGTO] = {bridge_ioctl_gto, sizeof(struct ifbrparam), BC_F_COPYOUT},
336 336
337[BRDGDADDR] = {bridge_ioctl_daddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},  337[BRDGDADDR] = {bridge_ioctl_daddr, sizeof(struct ifbareq), BC_F_COPYIN|BC_F_SUSER},
338 338
339[BRDGFLUSH] = {bridge_ioctl_flush, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},  339[BRDGFLUSH] = {bridge_ioctl_flush, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
340 340
341[BRDGGPRI] = {bridge_ioctl_gpri, sizeof(struct ifbrparam), BC_F_COPYOUT},  341[BRDGGPRI] = {bridge_ioctl_gpri, sizeof(struct ifbrparam), BC_F_COPYOUT},
342[BRDGSPRI] = {bridge_ioctl_spri, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  342[BRDGSPRI] = {bridge_ioctl_spri, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
343 343
344[BRDGGHT] = {bridge_ioctl_ght, sizeof(struct ifbrparam), BC_F_COPYOUT},  344[BRDGGHT] = {bridge_ioctl_ght, sizeof(struct ifbrparam), BC_F_COPYOUT},
345[BRDGSHT] = {bridge_ioctl_sht, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  345[BRDGSHT] = {bridge_ioctl_sht, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
346 346
347[BRDGGFD] = {bridge_ioctl_gfd, sizeof(struct ifbrparam), BC_F_COPYOUT},  347[BRDGGFD] = {bridge_ioctl_gfd, sizeof(struct ifbrparam), BC_F_COPYOUT},
348[BRDGSFD] = {bridge_ioctl_sfd, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  348[BRDGSFD] = {bridge_ioctl_sfd, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
349 349
350[BRDGGMA] = {bridge_ioctl_gma, sizeof(struct ifbrparam), BC_F_COPYOUT},  350[BRDGGMA] = {bridge_ioctl_gma, sizeof(struct ifbrparam), BC_F_COPYOUT},
351[BRDGSMA] = {bridge_ioctl_sma, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},  351[BRDGSMA] = {bridge_ioctl_sma, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
352 352
353[BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},  353[BRDGSIFPRIO] = {bridge_ioctl_sifprio, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
354 354
355[BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},  355[BRDGSIFCOST] = {bridge_ioctl_sifcost, sizeof(struct ifbreq), BC_F_COPYIN|BC_F_SUSER},
356#if defined(BRIDGE_IPF) 356#if defined(BRIDGE_IPF)
357[BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT}, 357[BRDGGFILT] = {bridge_ioctl_gfilt, sizeof(struct ifbrparam), BC_F_COPYOUT},
358[BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER}, 358[BRDGSFILT] = {bridge_ioctl_sfilt, sizeof(struct ifbrparam), BC_F_COPYIN|BC_F_SUSER},
359#endif /* BRIDGE_IPF */ 359#endif /* BRIDGE_IPF */
360[BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT}, 360[BRDGGIFS] = {bridge_ioctl_gifs, sizeof(struct ifbifconf), BC_F_XLATEIN|BC_F_XLATEOUT},
361[BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT}, 361[BRDGRTS] = {bridge_ioctl_rts, sizeof(struct ifbaconf), BC_F_XLATEIN|BC_F_XLATEOUT},
362}; 362};
363 363
364static const int bridge_control_table_size = __arraycount(bridge_control_table); 364static const int bridge_control_table_size = __arraycount(bridge_control_table);
365 365
366static struct if_clone bridge_cloner = 366static struct if_clone bridge_cloner =
367 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy); 367 IF_CLONE_INITIALIZER("bridge", bridge_clone_create, bridge_clone_destroy);
368 368
369/* 369/*
370 * bridgeattach: 370 * bridgeattach:
371 * 371 *
372 * Pseudo-device attach routine. 372 * Pseudo-device attach routine.
373 */ 373 */
374void 374void
375bridgeattach(int n) 375bridgeattach(int n)
376{ 376{
377 377
378 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode), 378 pool_init(&bridge_rtnode_pool, sizeof(struct bridge_rtnode),
379 0, 0, 0, "brtpl", NULL, IPL_NET); 379 0, 0, 0, "brtpl", NULL, IPL_NET);
380 380
381 bridge_psref_class = psref_class_create("bridge", IPL_SOFTNET); 381 bridge_psref_class = psref_class_create("bridge", IPL_SOFTNET);
382 382
383 if_clone_attach(&bridge_cloner); 383 if_clone_attach(&bridge_cloner);
384} 384}
385 385
386/* 386/*
387 * bridge_clone_create: 387 * bridge_clone_create:
388 * 388 *
389 * Create a new bridge instance. 389 * Create a new bridge instance.
390 */ 390 */
391static int 391static int
392bridge_clone_create(struct if_clone *ifc, int unit) 392bridge_clone_create(struct if_clone *ifc, int unit)
393{ 393{
394 struct bridge_softc *sc; 394 struct bridge_softc *sc;
395 struct ifnet *ifp; 395 struct ifnet *ifp;
396 int error; 396 int error;
397 397
398 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 398 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
399 ifp = &sc->sc_if; 399 ifp = &sc->sc_if;
400 400
401 sc->sc_brtmax = BRIDGE_RTABLE_MAX; 401 sc->sc_brtmax = BRIDGE_RTABLE_MAX;
402 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; 402 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
403 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE; 403 sc->sc_bridge_max_age = BSTP_DEFAULT_MAX_AGE;
404 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME; 404 sc->sc_bridge_hello_time = BSTP_DEFAULT_HELLO_TIME;
405 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY; 405 sc->sc_bridge_forward_delay = BSTP_DEFAULT_FORWARD_DELAY;
406 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY; 406 sc->sc_bridge_priority = BSTP_DEFAULT_BRIDGE_PRIORITY;
407 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME; 407 sc->sc_hold_time = BSTP_DEFAULT_HOLD_TIME;
408 sc->sc_filter_flags = 0; 408 sc->sc_filter_flags = 0;
409 409
410 /* Initialize our routing table. */ 410 /* Initialize our routing table. */
411 bridge_rtable_init(sc); 411 bridge_rtable_init(sc);
412 412
413 error = workqueue_create(&sc->sc_rtage_wq, "bridge_rtage", 413 error = workqueue_create(&sc->sc_rtage_wq, "bridge_rtage",
414 bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE); 414 bridge_rtage_work, sc, PRI_SOFTNET, IPL_SOFTNET, WQ_MPSAFE);
415 if (error) 415 if (error)
416 panic("%s: workqueue_create %d\n", __func__, error); 416 panic("%s: workqueue_create %d\n", __func__, error);
417 417
418 callout_init(&sc->sc_brcallout, CALLOUT_MPSAFE); 418 callout_init(&sc->sc_brcallout, CALLOUT_MPSAFE);
419 callout_init(&sc->sc_bstpcallout, CALLOUT_MPSAFE); 419 callout_init(&sc->sc_bstpcallout, CALLOUT_MPSAFE);
420 420
421 mutex_init(&sc->sc_iflist_psref.bip_lock, MUTEX_DEFAULT, IPL_NONE); 421 mutex_init(&sc->sc_iflist_psref.bip_lock, MUTEX_DEFAULT, IPL_NONE);
422 PSLIST_INIT(&sc->sc_iflist_psref.bip_iflist); 422 PSLIST_INIT(&sc->sc_iflist_psref.bip_iflist);
423 sc->sc_iflist_psref.bip_psz = pserialize_create(); 423 sc->sc_iflist_psref.bip_psz = pserialize_create();
424 424
425 if_initname(ifp, ifc->ifc_name, unit); 425 if_initname(ifp, ifc->ifc_name, unit);
426 ifp->if_softc = sc; 426 ifp->if_softc = sc;
427 ifp->if_extflags = IFEF_NO_LINK_STATE_CHANGE; 427 ifp->if_extflags = IFEF_NO_LINK_STATE_CHANGE;
428#ifdef NET_MPSAFE 428#ifdef NET_MPSAFE
429 ifp->if_extflags |= IFEF_MPSAFE; 429 ifp->if_extflags |= IFEF_MPSAFE;
430#endif 430#endif
431 ifp->if_mtu = ETHERMTU; 431 ifp->if_mtu = ETHERMTU;
432 ifp->if_ioctl = bridge_ioctl; 432 ifp->if_ioctl = bridge_ioctl;
433 ifp->if_output = bridge_output; 433 ifp->if_output = bridge_output;
434 ifp->if_start = bridge_start; 434 ifp->if_start = bridge_start;
435 ifp->if_stop = bridge_stop; 435 ifp->if_stop = bridge_stop;
436 ifp->if_init = bridge_init; 436 ifp->if_init = bridge_init;
437 ifp->if_type = IFT_BRIDGE; 437 ifp->if_type = IFT_BRIDGE;
438 ifp->if_addrlen = 0; 438 ifp->if_addrlen = 0;
439 ifp->if_dlt = DLT_EN10MB; 439 ifp->if_dlt = DLT_EN10MB;
440 ifp->if_hdrlen = ETHER_HDR_LEN; 440 ifp->if_hdrlen = ETHER_HDR_LEN;
441 441
442 error = if_initialize(ifp); 442 error = if_initialize(ifp);
443 if (error != 0) { 443 if (error != 0) {
444 pserialize_destroy(sc->sc_iflist_psref.bip_psz); 444 pserialize_destroy(sc->sc_iflist_psref.bip_psz);
445 mutex_destroy(&sc->sc_iflist_psref.bip_lock); 445 mutex_destroy(&sc->sc_iflist_psref.bip_lock);
446 callout_destroy(&sc->sc_brcallout); 446 callout_destroy(&sc->sc_brcallout);
447 callout_destroy(&sc->sc_bstpcallout); 447 callout_destroy(&sc->sc_bstpcallout);
448 workqueue_destroy(sc->sc_rtage_wq); 448 workqueue_destroy(sc->sc_rtage_wq);
449 bridge_rtable_fini(sc); 449 bridge_rtable_fini(sc);
450 kmem_free(sc, sizeof(*sc)); 450 kmem_free(sc, sizeof(*sc));
451 451
452 return error; 452 return error;
453 } 453 }
454 if_register(ifp); 454 if_register(ifp);
455 455
456 if_alloc_sadl(ifp); 456 if_alloc_sadl(ifp);
457 457
458 return 0; 458 return 0;
459} 459}
460 460
461/* 461/*
462 * bridge_clone_destroy: 462 * bridge_clone_destroy:
463 * 463 *
464 * Destroy a bridge instance. 464 * Destroy a bridge instance.
465 */ 465 */
466static int 466static int
467bridge_clone_destroy(struct ifnet *ifp) 467bridge_clone_destroy(struct ifnet *ifp)
468{ 468{
469 struct bridge_softc *sc = ifp->if_softc; 469 struct bridge_softc *sc = ifp->if_softc;
470 struct bridge_iflist *bif; 470 struct bridge_iflist *bif;
471 471
472 bridge_stop(ifp, 1); 472 bridge_stop(ifp, 1);
473 473
474 BRIDGE_LOCK(sc); 474 BRIDGE_LOCK(sc);
475 for (;;) { 475 for (;;) {
476 bif = PSLIST_WRITER_FIRST(&sc->sc_iflist_psref.bip_iflist, struct bridge_iflist, 476 bif = PSLIST_WRITER_FIRST(&sc->sc_iflist_psref.bip_iflist, struct bridge_iflist,
477 bif_next); 477 bif_next);
478 if (bif == NULL) 478 if (bif == NULL)
479 break; 479 break;
480 bridge_delete_member(sc, bif); 480 bridge_delete_member(sc, bif);
481 } 481 }
482 PSLIST_DESTROY(&sc->sc_iflist_psref.bip_iflist); 482 PSLIST_DESTROY(&sc->sc_iflist_psref.bip_iflist);
483 BRIDGE_UNLOCK(sc); 483 BRIDGE_UNLOCK(sc);
484 484
485 if_detach(ifp); 485 if_detach(ifp);
486 486
487 /* Tear down the routing table. */ 487 /* Tear down the routing table. */
488 bridge_rtable_fini(sc); 488 bridge_rtable_fini(sc);
489 489
490 pserialize_destroy(sc->sc_iflist_psref.bip_psz); 490 pserialize_destroy(sc->sc_iflist_psref.bip_psz);
491 mutex_destroy(&sc->sc_iflist_psref.bip_lock); 491 mutex_destroy(&sc->sc_iflist_psref.bip_lock);
492 callout_destroy(&sc->sc_brcallout); 492 callout_destroy(&sc->sc_brcallout);
493 callout_destroy(&sc->sc_bstpcallout); 493 callout_destroy(&sc->sc_bstpcallout);
494 workqueue_destroy(sc->sc_rtage_wq); 494 workqueue_destroy(sc->sc_rtage_wq);
495 kmem_free(sc, sizeof(*sc)); 495 kmem_free(sc, sizeof(*sc));
496 496
497 return 0; 497 return 0;
498} 498}
499 499
500/* 500/*
501 * bridge_ioctl: 501 * bridge_ioctl:
502 * 502 *
503 * Handle a control request from the operator. 503 * Handle a control request from the operator.
504 */ 504 */
505static int 505static int
506bridge_ioctl(struct ifnet *ifp, u_long cmd, void *data) 506bridge_ioctl(struct ifnet *ifp, u_long cmd, void *data)
507{ 507{
508 struct bridge_softc *sc = ifp->if_softc; 508 struct bridge_softc *sc = ifp->if_softc;
509 struct lwp *l = curlwp; /* XXX */ 509 struct lwp *l = curlwp; /* XXX */
510 union { 510 union {
511 struct ifbreq ifbreq; 511 struct ifbreq ifbreq;
512 struct ifbifconf ifbifconf; 512 struct ifbifconf ifbifconf;
513 struct ifbareq ifbareq; 513 struct ifbareq ifbareq;
514 struct ifbaconf ifbaconf; 514 struct ifbaconf ifbaconf;
515 struct ifbrparam ifbrparam; 515 struct ifbrparam ifbrparam;
516 } args; 516 } args;
517 struct ifdrv *ifd = (struct ifdrv *) data; 517 struct ifdrv *ifd = (struct ifdrv *) data;
518 const struct bridge_control *bc = NULL; /* XXXGCC */ 518 const struct bridge_control *bc = NULL; /* XXXGCC */
519 int s, error = 0; 519 int s, error = 0;
520 520
521 /* Authorize command before calling splsoftnet(). */ 521 /* Authorize command before calling splsoftnet(). */
522 switch (cmd) { 522 switch (cmd) {
523 case SIOCGDRVSPEC: 523 case SIOCGDRVSPEC:
524 case SIOCSDRVSPEC: 524 case SIOCSDRVSPEC:
525 if (ifd->ifd_cmd >= bridge_control_table_size 525 if (ifd->ifd_cmd >= bridge_control_table_size
526 || (bc = &bridge_control_table[ifd->ifd_cmd]) == NULL) { 526 || (bc = &bridge_control_table[ifd->ifd_cmd]) == NULL) {
527 error = EINVAL; 527 error = EINVAL;
528 return error; 528 return error;
529 } 529 }
530 530
531 /* We only care about BC_F_SUSER at this point. */ 531 /* We only care about BC_F_SUSER at this point. */
532 if ((bc->bc_flags & BC_F_SUSER) == 0) 532 if ((bc->bc_flags & BC_F_SUSER) == 0)
533 break; 533 break;
534 534
535 error = kauth_authorize_network(l->l_cred, 535 error = kauth_authorize_network(l->l_cred,
536 KAUTH_NETWORK_INTERFACE_BRIDGE, 536 KAUTH_NETWORK_INTERFACE_BRIDGE,
537 cmd == SIOCGDRVSPEC ? 537 cmd == SIOCGDRVSPEC ?
538 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV : 538 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV :
539 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV, 539 KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV,
540 ifd, NULL, NULL); 540 ifd, NULL, NULL);
541 if (error) 541 if (error)
542 return error; 542 return error;
543 543
544 break; 544 break;
545 } 545 }
546 546
547 s = splsoftnet(); 547 s = splsoftnet();
548 548
549 switch (cmd) { 549 switch (cmd) {
550 case SIOCGDRVSPEC: 550 case SIOCGDRVSPEC:
551 case SIOCSDRVSPEC: 551 case SIOCSDRVSPEC:
552 KASSERT(bc != NULL); 552 KASSERT(bc != NULL);
553 if (cmd == SIOCGDRVSPEC && 553 if (cmd == SIOCGDRVSPEC &&
554 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) == 0) { 554 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) == 0) {
555 error = EINVAL; 555 error = EINVAL;
556 break; 556 break;
557 } 557 }
558 else if (cmd == SIOCSDRVSPEC && 558 else if (cmd == SIOCSDRVSPEC &&
559 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) != 0) { 559 (bc->bc_flags & (BC_F_COPYOUT|BC_F_XLATEOUT)) != 0) {
560 error = EINVAL; 560 error = EINVAL;
561 break; 561 break;
562 } 562 }
563 563
564 /* BC_F_SUSER is checked above, before splsoftnet(). */ 564 /* BC_F_SUSER is checked above, before splsoftnet(). */
565 565
566 if ((bc->bc_flags & (BC_F_XLATEIN|BC_F_XLATEOUT)) == 0 566 if ((bc->bc_flags & (BC_F_XLATEIN|BC_F_XLATEOUT)) == 0
567 && (ifd->ifd_len != bc->bc_argsize 567 && (ifd->ifd_len != bc->bc_argsize
568 || ifd->ifd_len > sizeof(args))) { 568 || ifd->ifd_len > sizeof(args))) {
569 error = EINVAL; 569 error = EINVAL;
570 break; 570 break;
571 } 571 }
572 572
573 memset(&args, 0, sizeof(args)); 573 memset(&args, 0, sizeof(args));
574 if (bc->bc_flags & BC_F_COPYIN) { 574 if (bc->bc_flags & BC_F_COPYIN) {
575 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); 575 error = copyin(ifd->ifd_data, &args, ifd->ifd_len);
576 if (error) 576 if (error)
577 break; 577 break;
578 } else if (bc->bc_flags & BC_F_XLATEIN) { 578 } else if (bc->bc_flags & BC_F_XLATEIN) {
579 args.ifbifconf.ifbic_len = ifd->ifd_len; 579 args.ifbifconf.ifbic_len = ifd->ifd_len;
580 args.ifbifconf.ifbic_buf = ifd->ifd_data; 580 args.ifbifconf.ifbic_buf = ifd->ifd_data;
581 } 581 }
582 582
583 error = (*bc->bc_func)(sc, &args); 583 error = (*bc->bc_func)(sc, &args);
584 if (error) 584 if (error)
585 break; 585 break;
586 586
587 if (bc->bc_flags & BC_F_COPYOUT) { 587 if (bc->bc_flags & BC_F_COPYOUT) {
588 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); 588 error = copyout(&args, ifd->ifd_data, ifd->ifd_len);
589 } else if (bc->bc_flags & BC_F_XLATEOUT) { 589 } else if (bc->bc_flags & BC_F_XLATEOUT) {
590 ifd->ifd_len = args.ifbifconf.ifbic_len; 590 ifd->ifd_len = args.ifbifconf.ifbic_len;
591 ifd->ifd_data = args.ifbifconf.ifbic_buf; 591 ifd->ifd_data = args.ifbifconf.ifbic_buf;
592 } 592 }
593 break; 593 break;
594 594
595 case SIOCSIFFLAGS: 595 case SIOCSIFFLAGS:
596 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 596 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
597 break; 597 break;
598 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) { 598 switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
599 case IFF_RUNNING: 599 case IFF_RUNNING:
600 /* 600 /*
601 * If interface is marked down and it is running, 601 * If interface is marked down and it is running,
602 * then stop and disable it. 602 * then stop and disable it.
603 */ 603 */
604 (*ifp->if_stop)(ifp, 1); 604 (*ifp->if_stop)(ifp, 1);
605 break; 605 break;
606 case IFF_UP: 606 case IFF_UP:
607 /* 607 /*
608 * If interface is marked up and it is stopped, then 608 * If interface is marked up and it is stopped, then
609 * start it. 609 * start it.
610 */ 610 */
611 error = (*ifp->if_init)(ifp); 611 error = (*ifp->if_init)(ifp);
612 break; 612 break;
613 default: 613 default:
614 break; 614 break;
615 } 615 }
616 break; 616 break;
617 617
618 case SIOCSIFMTU: 618 case SIOCSIFMTU:
619 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 619 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
620 error = 0; 620 error = 0;
621 break; 621 break;
622 622
623 default: 623 default:
624 error = ifioctl_common(ifp, cmd, data); 624 error = ifioctl_common(ifp, cmd, data);
625 break; 625 break;
626 } 626 }
627 627
628 splx(s); 628 splx(s);
629 629
630 return error; 630 return error;
631} 631}
632 632
633/* 633/*
634 * bridge_lookup_member: 634 * bridge_lookup_member:
635 * 635 *
636 * Lookup a bridge member interface. 636 * Lookup a bridge member interface.
637 */ 637 */
638static struct bridge_iflist * 638static struct bridge_iflist *
639bridge_lookup_member(struct bridge_softc *sc, const char *name, struct psref *psref) 639bridge_lookup_member(struct bridge_softc *sc, const char *name, struct psref *psref)
640{ 640{
641 struct bridge_iflist *bif; 641 struct bridge_iflist *bif;
642 struct ifnet *ifp; 642 struct ifnet *ifp;
643 int s; 643 int s;
644 644
645 BRIDGE_PSZ_RENTER(s); 645 BRIDGE_PSZ_RENTER(s);
646 646
647 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 647 BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
648 ifp = bif->bif_ifp; 648 ifp = bif->bif_ifp;
649 if (strcmp(ifp->if_xname, name) == 0) 649 if (strcmp(ifp->if_xname, name) == 0)
650 break; 650 break;
651 } 651 }
652 if (bif != NULL) 652 if (bif != NULL)
653 bridge_acquire_member(sc, bif, psref); 653 bridge_acquire_member(sc, bif, psref);
654 654
655 BRIDGE_PSZ_REXIT(s); 655 BRIDGE_PSZ_REXIT(s);
656 656
657 return bif; 657 return bif;
658} 658}
659 659
660/* 660/*
661 * bridge_lookup_member_if: 661 * bridge_lookup_member_if:
662 * 662 *
663 * Lookup a bridge member interface by ifnet*. 663 * Lookup a bridge member interface by ifnet*.
664 */ 664 */
665static struct bridge_iflist * 665static struct bridge_iflist *
666bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp, 666bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp,
667 struct psref *psref) 667 struct psref *psref)
668{ 668{
669 struct bridge_iflist *bif; 669 struct bridge_iflist *bif;
670 int s; 670 int s;
671 671
672 BRIDGE_PSZ_RENTER(s); 672 BRIDGE_PSZ_RENTER(s);
673 673
674 bif = member_ifp->if_bridgeif; 674 bif = member_ifp->if_bridgeif;
675 if (bif != NULL) { 675 if (bif != NULL) {
676 psref_acquire(psref, &bif->bif_psref, 676 psref_acquire(psref, &bif->bif_psref,
677 bridge_psref_class); 677 bridge_psref_class);
678 } 678 }
679 679
680 BRIDGE_PSZ_REXIT(s); 680 BRIDGE_PSZ_REXIT(s);
681 681
682 return bif; 682 return bif;
683} 683}
684 684
685static void 685static void
686bridge_acquire_member(struct bridge_softc *sc, struct bridge_iflist *bif, 686bridge_acquire_member(struct bridge_softc *sc, struct bridge_iflist *bif,
687 struct psref *psref) 687 struct psref *psref)
688{ 688{
689 689
690 psref_acquire(psref, &bif->bif_psref, bridge_psref_class); 690 psref_acquire(psref, &bif->bif_psref, bridge_psref_class);
691} 691}
692 692
693/* 693/*
694 * bridge_release_member: 694 * bridge_release_member:
695 * 695 *
696 * Release the specified member interface. 696 * Release the specified member interface.
697 */ 697 */
698static void 698static void
699bridge_release_member(struct bridge_softc *sc, struct bridge_iflist *bif, 699bridge_release_member(struct bridge_softc *sc, struct bridge_iflist *bif,
700 struct psref *psref) 700 struct psref *psref)
701{ 701{
702 702
703 psref_release(psref, &bif->bif_psref, bridge_psref_class); 703 psref_release(psref, &bif->bif_psref, bridge_psref_class);
704} 704}
705 705
706/* 706/*
707 * bridge_delete_member: 707 * bridge_delete_member:
708 * 708 *
709 * Delete the specified member interface. 709 * Delete the specified member interface.
710 */ 710 */
711static void 711static void
712bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif) 712bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif)
713{ 713{
714 struct ifnet *ifs = bif->bif_ifp; 714 struct ifnet *ifs = bif->bif_ifp;
715 715
716 KASSERT(BRIDGE_LOCKED(sc)); 716 KASSERT(BRIDGE_LOCKED(sc));
717 717
718 ifs->_if_input = ether_input; 718 ifs->_if_input = ether_input;
719 ifs->if_bridge = NULL; 719 ifs->if_bridge = NULL;
720 ifs->if_bridgeif = NULL; 720 ifs->if_bridgeif = NULL;
721 721
722 PSLIST_WRITER_REMOVE(bif, bif_next); 722 PSLIST_WRITER_REMOVE(bif, bif_next);
723 BRIDGE_PSZ_PERFORM(sc); 723 BRIDGE_PSZ_PERFORM(sc);
724 BRIDGE_UNLOCK(sc); 724 BRIDGE_UNLOCK(sc);
725 725
726 psref_target_destroy(&bif->bif_psref, bridge_psref_class); 726 psref_target_destroy(&bif->bif_psref, bridge_psref_class);
727 727
728 PSLIST_ENTRY_DESTROY(bif, bif_next); 728 PSLIST_ENTRY_DESTROY(bif, bif_next);
729 kmem_free(bif, sizeof(*bif)); 729 kmem_free(bif, sizeof(*bif));
730 730
731 BRIDGE_LOCK(sc); 731 BRIDGE_LOCK(sc);
732} 732}
733 733
734static int 734static int
735bridge_ioctl_add(struct bridge_softc *sc, void *arg) 735bridge_ioctl_add(struct bridge_softc *sc, void *arg)
736{ 736{
737 struct ifbreq *req = arg; 737 struct ifbreq *req = arg;
738 struct bridge_iflist *bif = NULL; 738 struct bridge_iflist *bif = NULL;
739 struct ifnet *ifs; 739 struct ifnet *ifs;
740 int error = 0; 740 int error = 0;
741 struct psref psref; 741 struct psref psref;
742 742
743 ifs = if_get(req->ifbr_ifsname, &psref); 743 ifs = if_get(req->ifbr_ifsname, &psref);
744 if (ifs == NULL) 744 if (ifs == NULL)
745 return ENOENT; 745 return ENOENT;
746 746
747 if (ifs->if_bridge == sc) { 747 if (ifs->if_bridge == sc) {
748 error = EEXIST; 748 error = EEXIST;
749 goto out; 749 goto out;
750 } 750 }
751 751
752 if (ifs->if_bridge != NULL) { 752 if (ifs->if_bridge != NULL) {
753 error = EBUSY; 753 error = EBUSY;
754 goto out; 754 goto out;
755 } 755 }
756 756
757 if (ifs->_if_input != ether_input) { 757 if (ifs->_if_input != ether_input) {
758 error = EINVAL; 758 error = EINVAL;
759 goto out; 759 goto out;
760 } 760 }
761 761
762 /* FIXME: doesn't work with non-IFF_SIMPLEX interfaces */ 762 /* FIXME: doesn't work with non-IFF_SIMPLEX interfaces */
763 if ((ifs->if_flags & IFF_SIMPLEX) == 0) { 763 if ((ifs->if_flags & IFF_SIMPLEX) == 0) {
764 error = EINVAL; 764 error = EINVAL;
765 goto out; 765 goto out;
766 } 766 }
767 767
768 bif = kmem_alloc(sizeof(*bif), KM_SLEEP); 768 bif = kmem_alloc(sizeof(*bif), KM_SLEEP);
769 769
770 switch (ifs->if_type) { 770 switch (ifs->if_type) {
771 case IFT_ETHER: 771 case IFT_ETHER:
772 if (sc->sc_if.if_mtu != ifs->if_mtu) { 772 if (sc->sc_if.if_mtu != ifs->if_mtu) {
773 error = EINVAL; 773 error = EINVAL;
774 goto out; 774 goto out;
775 } 775 }
776 /* FALLTHROUGH */ 776 /* FALLTHROUGH */
777 case IFT_L2TP: 777 case IFT_L2TP:
778 IFNET_LOCK(ifs); 778 IFNET_LOCK(ifs);
779 error = ether_enable_vlan_mtu(ifs); 779 error = ether_enable_vlan_mtu(ifs);
780 IFNET_UNLOCK(ifs); 780 IFNET_UNLOCK(ifs);
781 if (error > 0) 781 if (error > 0)
782 goto out; 782 goto out;
783 /* 783 /*
784 * Place the interface into promiscuous mode. 784 * Place the interface into promiscuous mode.
785 */ 785 */
786 error = ifpromisc(ifs, 1); 786 error = ifpromisc(ifs, 1);
787 if (error) 787 if (error)
788 goto out; 788 goto out;
789 break; 789 break;
790 default: 790 default:
791 error = EINVAL; 791 error = EINVAL;
792 goto out; 792 goto out;
793 } 793 }
794 794
795 bif->bif_ifp = ifs; 795 bif->bif_ifp = ifs;
796 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; 796 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER;
797 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY; 797 bif->bif_priority = BSTP_DEFAULT_PORT_PRIORITY;
798 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST; 798 bif->bif_path_cost = BSTP_DEFAULT_PATH_COST;
799 PSLIST_ENTRY_INIT(bif, bif_next); 799 PSLIST_ENTRY_INIT(bif, bif_next);
800 psref_target_init(&bif->bif_psref, bridge_psref_class); 800 psref_target_init(&bif->bif_psref, bridge_psref_class);
801 801
802 BRIDGE_LOCK(sc); 802 BRIDGE_LOCK(sc);
803 803
804 ifs->if_bridge = sc; 804 ifs->if_bridge = sc;
805 ifs->if_bridgeif = bif; 805 ifs->if_bridgeif = bif;
806 PSLIST_WRITER_INSERT_HEAD(&sc->sc_iflist_psref.bip_iflist, bif, bif_next); 806 PSLIST_WRITER_INSERT_HEAD(&sc->sc_iflist_psref.bip_iflist, bif, bif_next);
807 ifs->_if_input = bridge_input; 807 ifs->_if_input = bridge_input;
808 808
809 BRIDGE_UNLOCK(sc); 809 BRIDGE_UNLOCK(sc);
810 810
811 if (sc->sc_if.if_flags & IFF_RUNNING) 811 if (sc->sc_if.if_flags & IFF_RUNNING)
812 bstp_initialization(sc); 812 bstp_initialization(sc);
813 else 813 else
814 bstp_stop(sc); 814 bstp_stop(sc);
815 815
816 out: 816 out:
817 if_put(ifs, &psref); 817 if_put(ifs, &psref);
818 if (error) { 818 if (error) {
819 if (bif != NULL) 819 if (bif != NULL)
820 kmem_free(bif, sizeof(*bif)); 820 kmem_free(bif, sizeof(*bif));
821 } 821 }
822 return error; 822 return error;
823} 823}
824 824
825static int 825static int
826bridge_ioctl_del(struct bridge_softc *sc, void *arg) 826bridge_ioctl_del(struct bridge_softc *sc, void *arg)
827{ 827{
828 struct ifbreq *req = arg; 828 struct ifbreq *req = arg;
829 const char *name = req->ifbr_ifsname; 829 const char *name = req->ifbr_ifsname;
830 struct bridge_iflist *bif; 830 struct bridge_iflist *bif;
831 struct ifnet *ifs; 831 struct ifnet *ifs;
832 832
833 BRIDGE_LOCK(sc); 833 BRIDGE_LOCK(sc);
834 834
835 /* 835 /*
836 * Don't use bridge_lookup_member. We want to get a member 836 * Don't use bridge_lookup_member. We want to get a member
837 * with bif_refs == 0. 837 * with bif_refs == 0.
838 */ 838 */
839 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) { 839 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
840 ifs = bif->bif_ifp; 840 ifs = bif->bif_ifp;
841 if (strcmp(ifs->if_xname, name) == 0) 841 if (strcmp(ifs->if_xname, name) == 0)
842 break; 842 break;
843 } 843 }
844 844
845 if (bif == NULL) { 845 if (bif == NULL) {
846 BRIDGE_UNLOCK(sc); 846 BRIDGE_UNLOCK(sc);
847 return ENOENT; 847 return ENOENT;
848 } 848 }
849 849
850 bridge_delete_member(sc, bif); 850 bridge_delete_member(sc, bif);
851 851
852 BRIDGE_UNLOCK(sc); 852 BRIDGE_UNLOCK(sc);
853 853
854 switch (ifs->if_type) { 854 switch (ifs->if_type) {
855 case IFT_ETHER: 855 case IFT_ETHER:
856 case IFT_L2TP: 856 case IFT_L2TP:
857 /* 857 /*
858 * Take the interface out of promiscuous mode. 858 * Take the interface out of promiscuous mode.
859 * Don't call it with holding a spin lock. 859 * Don't call it with holding a spin lock.
860 */ 860 */
861 (void) ifpromisc(ifs, 0); 861 (void) ifpromisc(ifs, 0);
862 IFNET_LOCK(ifs); 862 IFNET_LOCK(ifs);
863 (void) ether_disable_vlan_mtu(ifs); 863 (void) ether_disable_vlan_mtu(ifs);
864 IFNET_UNLOCK(ifs); 864 IFNET_UNLOCK(ifs);
865 break; 865 break;
866 default: 866 default:
867#ifdef DIAGNOSTIC 867#ifdef DIAGNOSTIC
868 panic("bridge_delete_member: impossible"); 868 panic("bridge_delete_member: impossible");
869#endif 869#endif
870 break; 870 break;
871 } 871 }
872 872
873 bridge_rtdelete(sc, ifs); 873 bridge_rtdelete(sc, ifs);
874 874
875 if (sc->sc_if.if_flags & IFF_RUNNING) 875 if (sc->sc_if.if_flags & IFF_RUNNING)
876 bstp_initialization(sc); 876 bstp_initialization(sc);
877 877
878 return 0; 878 return 0;
879} 879}
880 880
881static int 881static int
882bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg) 882bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
883{ 883{
884 struct ifbreq *req = arg; 884 struct ifbreq *req = arg;
885 struct bridge_iflist *bif; 885 struct bridge_iflist *bif;
886 struct psref psref; 886 struct psref psref;
887 887
888 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 888 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref);
889 if (bif == NULL) 889 if (bif == NULL)
890 return ENOENT; 890 return ENOENT;
891 891
892 req->ifbr_ifsflags = bif->bif_flags; 892 req->ifbr_ifsflags = bif->bif_flags;
893 req->ifbr_state = bif->bif_state; 893 req->ifbr_state = bif->bif_state;
894 req->ifbr_priority = bif->bif_priority; 894 req->ifbr_priority = bif->bif_priority;
895 req->ifbr_path_cost = bif->bif_path_cost; 895 req->ifbr_path_cost = bif->bif_path_cost;
896 req->ifbr_portno = bif->bif_ifp->if_index & 0xff; 896 req->ifbr_portno = bif->bif_ifp->if_index & 0xff;
897 897
898 bridge_release_member(sc, bif, &psref); 898 bridge_release_member(sc, bif, &psref);
899 899
900 return 0; 900 return 0;
901} 901}
902 902
903static int 903static int
904bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg) 904bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
905{ 905{
906 struct ifbreq *req = arg; 906 struct ifbreq *req = arg;
907 struct bridge_iflist *bif; 907 struct bridge_iflist *bif;
908 struct psref psref; 908 struct psref psref;
909 909
910 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 910 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref);
911 if (bif == NULL) 911 if (bif == NULL)
912 return ENOENT; 912 return ENOENT;
913 913
914 if (req->ifbr_ifsflags & IFBIF_STP) { 914 if (req->ifbr_ifsflags & IFBIF_STP) {
915 switch (bif->bif_ifp->if_type) { 915 switch (bif->bif_ifp->if_type) {
916 case IFT_ETHER: 916 case IFT_ETHER:
917 case IFT_L2TP: 917 case IFT_L2TP:
918 /* These can do spanning tree. */ 918 /* These can do spanning tree. */
919 break; 919 break;
920 920
921 default: 921 default:
922 /* Nothing else can. */ 922 /* Nothing else can. */
923 bridge_release_member(sc, bif, &psref); 923 bridge_release_member(sc, bif, &psref);
924 return EINVAL; 924 return EINVAL;
925 } 925 }
926 } 926 }
927 927
928 bif->bif_flags = req->ifbr_ifsflags; 928 bif->bif_flags = req->ifbr_ifsflags;
929 929
930 bridge_release_member(sc, bif, &psref); 930 bridge_release_member(sc, bif, &psref);
931 931
932 if (sc->sc_if.if_flags & IFF_RUNNING) 932 if (sc->sc_if.if_flags & IFF_RUNNING)
933 bstp_initialization(sc); 933 bstp_initialization(sc);
934 934
935 return 0; 935 return 0;
936} 936}
937 937
938static int 938static int
939bridge_ioctl_scache(struct bridge_softc *sc, void *arg) 939bridge_ioctl_scache(struct bridge_softc *sc, void *arg)
940{ 940{
941 struct ifbrparam *param = arg; 941 struct ifbrparam *param = arg;
942 942
943 sc->sc_brtmax = param->ifbrp_csize; 943 sc->sc_brtmax = param->ifbrp_csize;
944 bridge_rttrim(sc); 944 bridge_rttrim(sc);
945 945
946 return 0; 946 return 0;
947} 947}
948 948
949static int 949static int
950bridge_ioctl_gcache(struct bridge_softc *sc, void *arg) 950bridge_ioctl_gcache(struct bridge_softc *sc, void *arg)
951{ 951{
952 struct ifbrparam *param = arg; 952 struct ifbrparam *param = arg;
953 953
954 param->ifbrp_csize = sc->sc_brtmax; 954 param->ifbrp_csize = sc->sc_brtmax;
955 955
956 return 0; 956 return 0;
957} 957}
958 958
959static int 959static int
960bridge_ioctl_gifs(struct bridge_softc *sc, void *arg) 960bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
961{ 961{
962 struct ifbifconf *bifc = arg; 962 struct ifbifconf *bifc = arg;
963 struct bridge_iflist *bif; 963 struct bridge_iflist *bif;
964 struct ifbreq *breqs; 964 struct ifbreq *breqs;
965 int i, count, error = 0; 965 int i, count, error = 0;
966 966
967retry: 967retry:
968 BRIDGE_LOCK(sc); 968 BRIDGE_LOCK(sc);
969 count = 0; 969 count = 0;
970 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) 970 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc)
971 count++; 971 count++;
972 BRIDGE_UNLOCK(sc); 972 BRIDGE_UNLOCK(sc);
973 973
974 if (count == 0) { 974 if (count == 0) {
975 bifc->ifbic_len = 0; 975 bifc->ifbic_len = 0;
976 return 0; 976 return 0;
977 } 977 }
978 978
979 if (bifc->ifbic_len == 0 || bifc->ifbic_len < (sizeof(*breqs) * count)) { 979 if (bifc->ifbic_len == 0 || bifc->ifbic_len < (sizeof(*breqs) * count)) {
980 /* Tell that a larger buffer is needed */ 980 /* Tell that a larger buffer is needed */
981 bifc->ifbic_len = sizeof(*breqs) * count; 981 bifc->ifbic_len = sizeof(*breqs) * count;
982 return 0; 982 return 0;
983 } 983 }
984 984
985 breqs = kmem_alloc(sizeof(*breqs) * count, KM_SLEEP); 985 breqs = kmem_alloc(sizeof(*breqs) * count, KM_SLEEP);
986 986
987 BRIDGE_LOCK(sc); 987 BRIDGE_LOCK(sc);
988 988
989 i = 0; 989 i = 0;
990 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) 990 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc)
991 i++; 991 i++;
992 if (i > count) { 992 if (i > count) {
993 /* 993 /*
994 * The number of members has been increased. 994 * The number of members has been increased.
995 * We need more memory! 995 * We need more memory!
996 */ 996 */
997 BRIDGE_UNLOCK(sc); 997 BRIDGE_UNLOCK(sc);
998 kmem_free(breqs, sizeof(*breqs) * count); 998 kmem_free(breqs, sizeof(*breqs) * count);
999 goto retry; 999 goto retry;
1000 } 1000 }
1001 1001
1002 i = 0; 1002 i = 0;
1003 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) { 1003 BRIDGE_IFLIST_WRITER_FOREACH(bif, sc) {
1004 struct ifbreq *breq = &breqs[i++]; 1004 struct ifbreq *breq = &breqs[i++];
1005 memset(breq, 0, sizeof(*breq)); 1005 memset(breq, 0, sizeof(*breq));
1006 1006
1007 strlcpy(breq->ifbr_ifsname, bif->bif_ifp->if_xname, 1007 strlcpy(breq->ifbr_ifsname, bif->bif_ifp->if_xname,
1008 sizeof(breq->ifbr_ifsname)); 1008 sizeof(breq->ifbr_ifsname));
1009 breq->ifbr_ifsflags = bif->bif_flags; 1009 breq->ifbr_ifsflags = bif->bif_flags;
1010 breq->ifbr_state = bif->bif_state; 1010 breq->ifbr_state = bif->bif_state;
1011 breq->ifbr_priority = bif->bif_priority; 1011 breq->ifbr_priority = bif->bif_priority;
1012 breq->ifbr_path_cost = bif->bif_path_cost; 1012 breq->ifbr_path_cost = bif->bif_path_cost;
1013 breq->ifbr_portno = bif->bif_ifp->if_index & 0xff; 1013 breq->ifbr_portno = bif->bif_ifp->if_index & 0xff;
1014 } 1014 }
1015 1015
1016 /* Don't call copyout with holding the mutex */ 1016 /* Don't call copyout with holding the mutex */
1017 BRIDGE_UNLOCK(sc); 1017 BRIDGE_UNLOCK(sc);
1018 1018
1019 for (i = 0; i < count; i++) { 1019 for (i = 0; i < count; i++) {
1020 error = copyout(&breqs[i], bifc->ifbic_req + i, sizeof(*breqs)); 1020 error = copyout(&breqs[i], bifc->ifbic_req + i, sizeof(*breqs));
1021 if (error) 1021 if (error)
1022 break; 1022 break;
1023 } 1023 }
1024 bifc->ifbic_len = sizeof(*breqs) * i; 1024 bifc->ifbic_len = sizeof(*breqs) * i;
1025 1025
1026 kmem_free(breqs, sizeof(*breqs) * count); 1026 kmem_free(breqs, sizeof(*breqs) * count);
1027 1027
1028 return error; 1028 return error;
1029} 1029}
1030 1030
1031static int 1031static int
1032bridge_ioctl_rts(struct bridge_softc *sc, void *arg) 1032bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
1033{ 1033{
1034 struct ifbaconf *bac = arg; 1034 struct ifbaconf *bac = arg;
1035 struct bridge_rtnode *brt; 1035 struct bridge_rtnode *brt;
1036 struct ifbareq bareq; 1036 struct ifbareq bareq;
1037 int count = 0, error = 0, len; 1037 int count = 0, error = 0, len;
1038 1038
1039 if (bac->ifbac_len == 0) 1039 if (bac->ifbac_len == 0)
1040 return 0; 1040 return 0;
1041 1041
1042 BRIDGE_RT_LOCK(sc); 1042 BRIDGE_RT_LOCK(sc);
1043 1043
1044 len = bac->ifbac_len; 1044 len = bac->ifbac_len;
1045 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 1045 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
1046 if (len < sizeof(bareq)) 1046 if (len < sizeof(bareq))
1047 goto out; 1047 goto out;
1048 memset(&bareq, 0, sizeof(bareq)); 1048 memset(&bareq, 0, sizeof(bareq));
1049 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, 1049 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
1050 sizeof(bareq.ifba_ifsname)); 1050 sizeof(bareq.ifba_ifsname));
1051 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); 1051 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr));
1052 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 1052 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
1053 bareq.ifba_expire = brt->brt_expire - time_uptime; 1053 bareq.ifba_expire = brt->brt_expire - time_uptime;
1054 } else 1054 } else
1055 bareq.ifba_expire = 0; 1055 bareq.ifba_expire = 0;
1056 bareq.ifba_flags = brt->brt_flags; 1056 bareq.ifba_flags = brt->brt_flags;
1057 1057
1058 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq)); 1058 error = copyout(&bareq, bac->ifbac_req + count, sizeof(bareq));
1059 if (error) 1059 if (error)
1060 goto out; 1060 goto out;
1061 count++; 1061 count++;
1062 len -= sizeof(bareq); 1062 len -= sizeof(bareq);
1063 } 1063 }
1064 out: 1064 out:
1065 BRIDGE_RT_UNLOCK(sc); 1065 BRIDGE_RT_UNLOCK(sc);
1066 1066
1067 bac->ifbac_len = sizeof(bareq) * count; 1067 bac->ifbac_len = sizeof(bareq) * count;
1068 return error; 1068 return error;
1069} 1069}
1070 1070
1071static int 1071static int
1072bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) 1072bridge_ioctl_saddr(struct bridge_softc *sc, void *arg)
1073{ 1073{
1074 struct ifbareq *req = arg; 1074 struct ifbareq *req = arg;
1075 struct bridge_iflist *bif; 1075 struct bridge_iflist *bif;
1076 int error; 1076 int error;
1077 struct psref psref; 1077 struct psref psref;
1078 1078
1079 bif = bridge_lookup_member(sc, req->ifba_ifsname, &psref); 1079 bif = bridge_lookup_member(sc, req->ifba_ifsname, &psref);
1080 if (bif == NULL) 1080 if (bif == NULL)
1081 return ENOENT; 1081 return ENOENT;
1082 1082
1083 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1, 1083 error = bridge_rtupdate(sc, req->ifba_dst, bif->bif_ifp, 1,
1084 req->ifba_flags); 1084 req->ifba_flags);
1085 1085
1086 bridge_release_member(sc, bif, &psref); 1086 bridge_release_member(sc, bif, &psref);
1087 1087
1088 return error; 1088 return error;
1089} 1089}
1090 1090
1091static int 1091static int
1092bridge_ioctl_sto(struct bridge_softc *sc, void *arg) 1092bridge_ioctl_sto(struct bridge_softc *sc, void *arg)
1093{ 1093{
1094 struct ifbrparam *param = arg; 1094 struct ifbrparam *param = arg;
1095 1095
1096 sc->sc_brttimeout = param->ifbrp_ctime; 1096 sc->sc_brttimeout = param->ifbrp_ctime;
1097 1097
1098 return 0; 1098 return 0;
1099} 1099}
1100 1100
1101static int 1101static int
1102bridge_ioctl_gto(struct bridge_softc *sc, void *arg) 1102bridge_ioctl_gto(struct bridge_softc *sc, void *arg)
1103{ 1103{
1104 struct ifbrparam *param = arg; 1104 struct ifbrparam *param = arg;
1105 1105
1106 param->ifbrp_ctime = sc->sc_brttimeout; 1106 param->ifbrp_ctime = sc->sc_brttimeout;
1107 1107
1108 return 0; 1108 return 0;
1109} 1109}
1110 1110
1111static int 1111static int
1112bridge_ioctl_daddr(struct bridge_softc *sc, void *arg) 1112bridge_ioctl_daddr(struct bridge_softc *sc, void *arg)
1113{ 1113{
1114 struct ifbareq *req = arg; 1114 struct ifbareq *req = arg;
1115 1115
1116 return (bridge_rtdaddr(sc, req->ifba_dst)); 1116 return (bridge_rtdaddr(sc, req->ifba_dst));
1117} 1117}
1118 1118
1119static int 1119static int
1120bridge_ioctl_flush(struct bridge_softc *sc, void *arg) 1120bridge_ioctl_flush(struct bridge_softc *sc, void *arg)
1121{ 1121{
1122 struct ifbreq *req = arg; 1122 struct ifbreq *req = arg;
1123 1123
1124 bridge_rtflush(sc, req->ifbr_ifsflags); 1124 bridge_rtflush(sc, req->ifbr_ifsflags);
1125 1125
1126 return 0; 1126 return 0;
1127} 1127}
1128 1128
1129static int 1129static int
1130bridge_ioctl_gpri(struct bridge_softc *sc, void *arg) 1130bridge_ioctl_gpri(struct bridge_softc *sc, void *arg)
1131{ 1131{
1132 struct ifbrparam *param = arg; 1132 struct ifbrparam *param = arg;
1133 1133
1134 param->ifbrp_prio = sc->sc_bridge_priority; 1134 param->ifbrp_prio = sc->sc_bridge_priority;
1135 1135
1136 return 0; 1136 return 0;
1137} 1137}
1138 1138
1139static int 1139static int
1140bridge_ioctl_spri(struct bridge_softc *sc, void *arg) 1140bridge_ioctl_spri(struct bridge_softc *sc, void *arg)
1141{ 1141{
1142 struct ifbrparam *param = arg; 1142 struct ifbrparam *param = arg;
1143 1143
1144 sc->sc_bridge_priority = param->ifbrp_prio; 1144 sc->sc_bridge_priority = param->ifbrp_prio;
1145 1145
1146 if (sc->sc_if.if_flags & IFF_RUNNING) 1146 if (sc->sc_if.if_flags & IFF_RUNNING)
1147 bstp_initialization(sc); 1147 bstp_initialization(sc);
1148 1148
1149 return 0; 1149 return 0;
1150} 1150}
1151 1151
1152static int 1152static int
1153bridge_ioctl_ght(struct bridge_softc *sc, void *arg) 1153bridge_ioctl_ght(struct bridge_softc *sc, void *arg)
1154{ 1154{
1155 struct ifbrparam *param = arg; 1155 struct ifbrparam *param = arg;
1156 1156
1157 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8; 1157 param->ifbrp_hellotime = sc->sc_bridge_hello_time >> 8;
1158 1158
1159 return 0; 1159 return 0;
1160} 1160}
1161 1161
1162static int 1162static int
1163bridge_ioctl_sht(struct bridge_softc *sc, void *arg) 1163bridge_ioctl_sht(struct bridge_softc *sc, void *arg)
1164{ 1164{
1165 struct ifbrparam *param = arg; 1165 struct ifbrparam *param = arg;
1166 1166
1167 if (param->ifbrp_hellotime == 0) 1167 if (param->ifbrp_hellotime == 0)
1168 return EINVAL; 1168 return EINVAL;
1169 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8; 1169 sc->sc_bridge_hello_time = param->ifbrp_hellotime << 8;
1170 1170
1171 if (sc->sc_if.if_flags & IFF_RUNNING) 1171 if (sc->sc_if.if_flags & IFF_RUNNING)
1172 bstp_initialization(sc); 1172 bstp_initialization(sc);
1173 1173
1174 return 0; 1174 return 0;
1175} 1175}
1176 1176
1177static int 1177static int
1178bridge_ioctl_gfd(struct bridge_softc *sc, void *arg) 1178bridge_ioctl_gfd(struct bridge_softc *sc, void *arg)
1179{ 1179{
1180 struct ifbrparam *param = arg; 1180 struct ifbrparam *param = arg;
1181 1181
1182 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8; 1182 param->ifbrp_fwddelay = sc->sc_bridge_forward_delay >> 8;
1183 1183
1184 return 0; 1184 return 0;
1185} 1185}
1186 1186
1187static int 1187static int
1188bridge_ioctl_sfd(struct bridge_softc *sc, void *arg) 1188bridge_ioctl_sfd(struct bridge_softc *sc, void *arg)
1189{ 1189{
1190 struct ifbrparam *param = arg; 1190 struct ifbrparam *param = arg;
1191 1191
1192 if (param->ifbrp_fwddelay == 0) 1192 if (param->ifbrp_fwddelay == 0)
1193 return EINVAL; 1193 return EINVAL;
1194 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8; 1194 sc->sc_bridge_forward_delay = param->ifbrp_fwddelay << 8;
1195 1195
1196 if (sc->sc_if.if_flags & IFF_RUNNING) 1196 if (sc->sc_if.if_flags & IFF_RUNNING)
1197 bstp_initialization(sc); 1197 bstp_initialization(sc);
1198 1198
1199 return 0; 1199 return 0;
1200} 1200}
1201 1201
1202static int 1202static int
1203bridge_ioctl_gma(struct bridge_softc *sc, void *arg) 1203bridge_ioctl_gma(struct bridge_softc *sc, void *arg)
1204{ 1204{
1205 struct ifbrparam *param = arg; 1205 struct ifbrparam *param = arg;
1206 1206
1207 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8; 1207 param->ifbrp_maxage = sc->sc_bridge_max_age >> 8;
1208 1208
1209 return 0; 1209 return 0;
1210} 1210}
1211 1211
1212static int 1212static int
1213bridge_ioctl_sma(struct bridge_softc *sc, void *arg) 1213bridge_ioctl_sma(struct bridge_softc *sc, void *arg)
1214{ 1214{
1215 struct ifbrparam *param = arg; 1215 struct ifbrparam *param = arg;
1216 1216
1217 if (param->ifbrp_maxage == 0) 1217 if (param->ifbrp_maxage == 0)
1218 return EINVAL; 1218 return EINVAL;
1219 sc->sc_bridge_max_age = param->ifbrp_maxage << 8; 1219 sc->sc_bridge_max_age = param->ifbrp_maxage << 8;
1220 1220
1221 if (sc->sc_if.if_flags & IFF_RUNNING) 1221 if (sc->sc_if.if_flags & IFF_RUNNING)
1222 bstp_initialization(sc); 1222 bstp_initialization(sc);
1223 1223
1224 return 0; 1224 return 0;
1225} 1225}
1226 1226
1227static int 1227static int
1228bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg) 1228bridge_ioctl_sifprio(struct bridge_softc *sc, void *arg)
1229{ 1229{
1230 struct ifbreq *req = arg; 1230 struct ifbreq *req = arg;
1231 struct bridge_iflist *bif; 1231 struct bridge_iflist *bif;
1232 struct psref psref; 1232 struct psref psref;
1233 1233
1234 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 1234 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref);
1235 if (bif == NULL) 1235 if (bif == NULL)
1236 return ENOENT; 1236 return ENOENT;
1237 1237
1238 bif->bif_priority = req->ifbr_priority; 1238 bif->bif_priority = req->ifbr_priority;
1239 1239
1240 if (sc->sc_if.if_flags & IFF_RUNNING) 1240 if (sc->sc_if.if_flags & IFF_RUNNING)
1241 bstp_initialization(sc); 1241 bstp_initialization(sc);
1242 1242
1243 bridge_release_member(sc, bif, &psref); 1243 bridge_release_member(sc, bif, &psref);
1244 1244
1245 return 0; 1245 return 0;
1246} 1246}
1247 1247
1248#if defined(BRIDGE_IPF) 1248#if defined(BRIDGE_IPF)
1249static int 1249static int
1250bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg) 1250bridge_ioctl_gfilt(struct bridge_softc *sc, void *arg)
1251{ 1251{
1252 struct ifbrparam *param = arg; 1252 struct ifbrparam *param = arg;
1253 1253
1254 param->ifbrp_filter = sc->sc_filter_flags; 1254 param->ifbrp_filter = sc->sc_filter_flags;
1255 1255
1256 return 0; 1256 return 0;
1257} 1257}
1258 1258
1259static int 1259static int
1260bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg) 1260bridge_ioctl_sfilt(struct bridge_softc *sc, void *arg)
1261{ 1261{
1262 struct ifbrparam *param = arg; 1262 struct ifbrparam *param = arg;
1263 uint32_t nflags, oflags; 1263 uint32_t nflags, oflags;
1264 1264
1265 if (param->ifbrp_filter & ~IFBF_FILT_MASK) 1265 if (param->ifbrp_filter & ~IFBF_FILT_MASK)
1266 return EINVAL; 1266 return EINVAL;
1267 1267
1268 nflags = param->ifbrp_filter; 1268 nflags = param->ifbrp_filter;
1269 oflags = sc->sc_filter_flags; 1269 oflags = sc->sc_filter_flags;
1270 1270
1271 if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) { 1271 if ((nflags & IFBF_FILT_USEIPF) && !(oflags & IFBF_FILT_USEIPF)) {
1272 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1272 pfil_add_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
1273 sc->sc_if.if_pfil); 1273 sc->sc_if.if_pfil);
1274 } 1274 }
1275 if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) { 1275 if (!(nflags & IFBF_FILT_USEIPF) && (oflags & IFBF_FILT_USEIPF)) {
1276 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT, 1276 pfil_remove_hook((void *)bridge_ipf, NULL, PFIL_IN|PFIL_OUT,
1277 sc->sc_if.if_pfil); 1277 sc->sc_if.if_pfil);
1278 } 1278 }
1279 1279
1280 sc->sc_filter_flags = nflags; 1280 sc->sc_filter_flags = nflags;
1281 1281
1282 return 0; 1282 return 0;
1283} 1283}
1284#endif /* BRIDGE_IPF */ 1284#endif /* BRIDGE_IPF */
1285 1285
1286static int 1286static int
1287bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg) 1287bridge_ioctl_sifcost(struct bridge_softc *sc, void *arg)
1288{ 1288{
1289 struct ifbreq *req = arg; 1289 struct ifbreq *req = arg;
1290 struct bridge_iflist *bif; 1290 struct bridge_iflist *bif;
1291 struct psref psref; 1291 struct psref psref;
1292 1292
1293 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref); 1293 bif = bridge_lookup_member(sc, req->ifbr_ifsname, &psref);
1294 if (bif == NULL) 1294 if (bif == NULL)
1295 return ENOENT; 1295 return ENOENT;
1296 1296
1297 bif->bif_path_cost = req->ifbr_path_cost; 1297 bif->bif_path_cost = req->ifbr_path_cost;
1298 1298
1299 if (sc->sc_if.if_flags & IFF_RUNNING) 1299 if (sc->sc_if.if_flags & IFF_RUNNING)
1300 bstp_initialization(sc); 1300 bstp_initialization(sc);
1301 1301
1302 bridge_release_member(sc, bif, &psref); 1302 bridge_release_member(sc, bif, &psref);
1303 1303
1304 return 0; 1304 return 0;
1305} 1305}
1306 1306
1307/* 1307/*
1308 * bridge_ifdetach: 1308 * bridge_ifdetach:
1309 * 1309 *
1310 * Detach an interface from a bridge. Called when a member 1310 * Detach an interface from a bridge. Called when a member
1311 * interface is detaching. 1311 * interface is detaching.
1312 */ 1312 */
1313void 1313void
1314bridge_ifdetach(struct ifnet *ifp) 1314bridge_ifdetach(struct ifnet *ifp)
1315{ 1315{
1316 struct bridge_softc *sc = ifp->if_bridge; 1316 struct bridge_softc *sc = ifp->if_bridge;
1317 struct ifbreq breq; 1317 struct ifbreq breq;
1318 1318
1319 /* ioctl_lock should prevent this from happening */ 1319 /* ioctl_lock should prevent this from happening */
1320 KASSERT(sc != NULL); 1320 KASSERT(sc != NULL);
1321 1321
1322 memset(&breq, 0, sizeof(breq)); 1322 memset(&breq, 0, sizeof(breq));
1323 strlcpy(breq.ifbr_ifsname, ifp->if_xname, sizeof(breq.ifbr_ifsname)); 1323 strlcpy(breq.ifbr_ifsname, ifp->if_xname, sizeof(breq.ifbr_ifsname));
1324 1324
1325 (void) bridge_ioctl_del(sc, &breq); 1325 (void) bridge_ioctl_del(sc, &breq);
1326} 1326}
1327 1327
1328/* 1328/*
1329 * bridge_init: 1329 * bridge_init:
1330 * 1330 *
1331 * Initialize a bridge interface. 1331 * Initialize a bridge interface.
1332 */ 1332 */
1333static int 1333static int
1334bridge_init(struct ifnet *ifp) 1334bridge_init(struct ifnet *ifp)
1335{ 1335{
1336 struct bridge_softc *sc = ifp->if_softc; 1336 struct bridge_softc *sc = ifp->if_softc;
1337 1337
1338 KASSERT((ifp->if_flags & IFF_RUNNING) == 0); 1338 KASSERT((ifp->if_flags & IFF_RUNNING) == 0);
1339 1339
1340 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, 1340 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz,
1341 bridge_timer, sc); 1341 bridge_timer, sc);
1342 bstp_initialization(sc); 1342 bstp_initialization(sc);
1343 1343
1344 ifp->if_flags |= IFF_RUNNING; 1344 ifp->if_flags |= IFF_RUNNING;
1345 return 0; 1345 return 0;
1346} 1346}
1347 1347
1348/* 1348/*
1349 * bridge_stop: 1349 * bridge_stop:
1350 * 1350 *
1351 * Stop the bridge interface. 1351 * Stop the bridge interface.
1352 */ 1352 */
1353static void 1353static void
1354bridge_stop(struct ifnet *ifp, int disable) 1354bridge_stop(struct ifnet *ifp, int disable)
1355{ 1355{
1356 struct bridge_softc *sc = ifp->if_softc; 1356 struct bridge_softc *sc = ifp->if_softc;
1357 1357
1358 KASSERT((ifp->if_flags & IFF_RUNNING) != 0); 1358 KASSERT((ifp->if_flags & IFF_RUNNING) != 0);
1359 ifp->if_flags &= ~IFF_RUNNING; 1359 ifp->if_flags &= ~IFF_RUNNING;
1360 1360
1361 callout_stop(&sc->sc_brcallout); 1361 callout_halt(&sc->sc_brcallout, NULL);
 1362 workqueue_wait(sc->sc_rtage_wq, &sc->sc_rtage_wk);
1362 bstp_stop(sc); 1363 bstp_stop(sc);
1363 bridge_rtflush(sc, IFBF_FLUSHDYN); 1364 bridge_rtflush(sc, IFBF_FLUSHDYN);
1364} 1365}
1365 1366
1366/* 1367/*
1367 * bridge_enqueue: 1368 * bridge_enqueue:
1368 * 1369 *
1369 * Enqueue a packet on a bridge member interface. 1370 * Enqueue a packet on a bridge member interface.
1370 */ 1371 */
1371void 1372void
1372bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m, 1373bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m,
1373 int runfilt) 1374 int runfilt)
1374{ 1375{
1375 int len, error; 1376 int len, error;
1376 short mflags; 1377 short mflags;
1377 1378
1378 /* 1379 /*
1379 * Clear any in-bound checksum flags for this packet. 1380 * Clear any in-bound checksum flags for this packet.
1380 */ 1381 */
1381 m->m_pkthdr.csum_flags = 0; 1382 m->m_pkthdr.csum_flags = 0;
1382 1383
1383 if (runfilt) { 1384 if (runfilt) {
1384 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, 1385 if (pfil_run_hooks(sc->sc_if.if_pfil, &m,
1385 dst_ifp, PFIL_OUT) != 0) { 1386 dst_ifp, PFIL_OUT) != 0) {
1386 if (m != NULL) 1387 if (m != NULL)
1387 m_freem(m); 1388 m_freem(m);
1388 return; 1389 return;
1389 } 1390 }
1390 if (m == NULL) 1391 if (m == NULL)
1391 return; 1392 return;
1392 } 1393 }
1393 1394
1394#ifdef ALTQ 1395#ifdef ALTQ
1395 KERNEL_LOCK(1, NULL); 1396 KERNEL_LOCK(1, NULL);
1396 /* 1397 /*
1397 * If ALTQ is enabled on the member interface, do 1398 * If ALTQ is enabled on the member interface, do
1398 * classification; the queueing discipline might 1399 * classification; the queueing discipline might
1399 * not require classification, but might require 1400 * not require classification, but might require
1400 * the address family/header pointer in the pktattr. 1401 * the address family/header pointer in the pktattr.
1401 */ 1402 */
1402 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) { 1403 if (ALTQ_IS_ENABLED(&dst_ifp->if_snd)) {
1403 /* XXX IFT_ETHER */ 1404 /* XXX IFT_ETHER */
1404 altq_etherclassify(&dst_ifp->if_snd, m); 1405 altq_etherclassify(&dst_ifp->if_snd, m);
1405 } 1406 }
1406 KERNEL_UNLOCK_ONE(NULL); 1407 KERNEL_UNLOCK_ONE(NULL);
1407#endif /* ALTQ */ 1408#endif /* ALTQ */
1408 1409
1409 len = m->m_pkthdr.len; 1410 len = m->m_pkthdr.len;
1410 mflags = m->m_flags; 1411 mflags = m->m_flags;
1411 1412
1412 error = if_transmit_lock(dst_ifp, m); 1413 error = if_transmit_lock(dst_ifp, m);
1413 if (error) { 1414 if (error) {
1414 /* mbuf is already freed */ 1415 /* mbuf is already freed */
1415 sc->sc_if.if_oerrors++; 1416 sc->sc_if.if_oerrors++;
1416 return; 1417 return;
1417 } 1418 }
1418 1419
1419 sc->sc_if.if_opackets++; 1420 sc->sc_if.if_opackets++;
1420 sc->sc_if.if_obytes += len; 1421 sc->sc_if.if_obytes += len;
1421 if (mflags & M_MCAST) 1422 if (mflags & M_MCAST)
1422 sc->sc_if.if_omcasts++; 1423 sc->sc_if.if_omcasts++;
1423} 1424}
1424 1425
1425/* 1426/*
1426 * bridge_output: 1427 * bridge_output:
1427 * 1428 *
1428 * Send output from a bridge member interface. This 1429 * Send output from a bridge member interface. This
1429 * performs the bridging function for locally originated 1430 * performs the bridging function for locally originated
1430 * packets. 1431 * packets.
1431 * 1432 *
1432 * The mbuf has the Ethernet header already attached. We must 1433 * The mbuf has the Ethernet header already attached. We must
1433 * enqueue or free the mbuf before returning. 1434 * enqueue or free the mbuf before returning.
1434 */ 1435 */
1435int 1436int
1436bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa, 1437bridge_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *sa,
1437 const struct rtentry *rt) 1438 const struct rtentry *rt)
1438{ 1439{
1439 struct ether_header *eh; 1440 struct ether_header *eh;
1440 struct ifnet *dst_if; 1441 struct ifnet *dst_if;
1441 struct bridge_softc *sc; 1442 struct bridge_softc *sc;
1442 int s; 1443 int s;
1443 1444
1444 /* 1445 /*
1445 * bridge_output() is called from ether_output(), furthermore 1446 * bridge_output() is called from ether_output(), furthermore
1446 * ifp argument doesn't point to bridge(4). So, don't assert 1447 * ifp argument doesn't point to bridge(4). So, don't assert
1447 * IFEF_MPSAFE here. 1448 * IFEF_MPSAFE here.
1448 */ 1449 */
1449 1450
1450 if (m->m_len < ETHER_HDR_LEN) { 1451 if (m->m_len < ETHER_HDR_LEN) {
1451 m = m_pullup(m, ETHER_HDR_LEN); 1452 m = m_pullup(m, ETHER_HDR_LEN);
1452 if (m == NULL) 1453 if (m == NULL)
1453 return 0; 1454 return 0;
1454 } 1455 }
1455 1456
1456 eh = mtod(m, struct ether_header *); 1457 eh = mtod(m, struct ether_header *);
1457 sc = ifp->if_bridge; 1458 sc = ifp->if_bridge;
1458 1459
1459 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1460 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1460 if (memcmp(etherbroadcastaddr, 1461 if (memcmp(etherbroadcastaddr,
1461 eh->ether_dhost, ETHER_ADDR_LEN) == 0) 1462 eh->ether_dhost, ETHER_ADDR_LEN) == 0)
1462 m->m_flags |= M_BCAST; 1463 m->m_flags |= M_BCAST;
1463 else 1464 else
1464 m->m_flags |= M_MCAST; 1465 m->m_flags |= M_MCAST;
1465 } 1466 }
1466 1467
1467 /* 1468 /*
1468 * If bridge is down, but the original output interface is up, 1469 * If bridge is down, but the original output interface is up,
1469 * go ahead and send out that interface. Otherwise, the packet 1470 * go ahead and send out that interface. Otherwise, the packet
1470 * is dropped below. 1471 * is dropped below.
1471 */ 1472 */
1472 if (__predict_false(sc == NULL) || 1473 if (__predict_false(sc == NULL) ||
1473 (sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1474 (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1474 dst_if = ifp; 1475 dst_if = ifp;
1475 goto sendunicast; 1476 goto sendunicast;
1476 } 1477 }
1477 1478
1478 /* 1479 /*
1479 * If the packet is a multicast, or we don't know a better way to 1480 * If the packet is a multicast, or we don't know a better way to
1480 * get there, send to all interfaces. 1481 * get there, send to all interfaces.
1481 */ 1482 */
1482 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0) 1483 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0)
1483 dst_if = NULL; 1484 dst_if = NULL;
1484 else 1485 else
1485 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1486 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1486 if (dst_if == NULL) { 1487 if (dst_if == NULL) {
1487 /* XXX Should call bridge_broadcast, but there are locking 1488 /* XXX Should call bridge_broadcast, but there are locking
1488 * issues which need resolving first. */ 1489 * issues which need resolving first. */
1489 struct bridge_iflist *bif; 1490 struct bridge_iflist *bif;
1490 struct mbuf *mc; 1491 struct mbuf *mc;
1491 bool used = false; 1492 bool used = false;
1492 1493
1493 BRIDGE_PSZ_RENTER(s); 1494 BRIDGE_PSZ_RENTER(s);
1494 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 1495 BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
1495 struct psref psref; 1496 struct psref psref;
1496 1497
1497 bridge_acquire_member(sc, bif, &psref); 1498 bridge_acquire_member(sc, bif, &psref);
1498 BRIDGE_PSZ_REXIT(s); 1499 BRIDGE_PSZ_REXIT(s);
1499 1500
1500 dst_if = bif->bif_ifp; 1501 dst_if = bif->bif_ifp;
1501 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1502 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1502 goto next; 1503 goto next;
1503 1504
1504 /* 1505 /*
1505 * If this is not the original output interface, 1506 * If this is not the original output interface,
1506 * and the interface is participating in spanning 1507 * and the interface is participating in spanning
1507 * tree, make sure the port is in a state that 1508 * tree, make sure the port is in a state that
1508 * allows forwarding. 1509 * allows forwarding.
1509 */ 1510 */
1510 if (dst_if != ifp && 1511 if (dst_if != ifp &&
1511 (bif->bif_flags & IFBIF_STP) != 0) { 1512 (bif->bif_flags & IFBIF_STP) != 0) {
1512 switch (bif->bif_state) { 1513 switch (bif->bif_state) {
1513 case BSTP_IFSTATE_BLOCKING: 1514 case BSTP_IFSTATE_BLOCKING:
1514 case BSTP_IFSTATE_LISTENING: 1515 case BSTP_IFSTATE_LISTENING:
1515 case BSTP_IFSTATE_DISABLED: 1516 case BSTP_IFSTATE_DISABLED:
1516 goto next; 1517 goto next;
1517 } 1518 }
1518 } 1519 }
1519 1520
1520 if (PSLIST_READER_NEXT(bif, struct bridge_iflist, 1521 if (PSLIST_READER_NEXT(bif, struct bridge_iflist,
1521 bif_next) == NULL && 1522 bif_next) == NULL &&
1522 ((m->m_flags & (M_MCAST | M_BCAST)) == 0 || 1523 ((m->m_flags & (M_MCAST | M_BCAST)) == 0 ||
1523 dst_if == ifp)) 1524 dst_if == ifp))
1524 { 1525 {
1525 used = true; 1526 used = true;
1526 mc = m; 1527 mc = m;
1527 } else { 1528 } else {
1528 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); 1529 mc = m_copym(m, 0, M_COPYALL, M_NOWAIT);
1529 if (mc == NULL) { 1530 if (mc == NULL) {
1530 sc->sc_if.if_oerrors++; 1531 sc->sc_if.if_oerrors++;
1531 goto next; 1532 goto next;
1532 } 1533 }
1533 } 1534 }
1534 1535
1535 bridge_enqueue(sc, dst_if, mc, 0); 1536 bridge_enqueue(sc, dst_if, mc, 0);
1536 1537
1537 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0 && 1538 if ((m->m_flags & (M_MCAST | M_BCAST)) != 0 &&
1538 dst_if != ifp) 1539 dst_if != ifp)
1539 { 1540 {
1540 if (PSLIST_READER_NEXT(bif, 1541 if (PSLIST_READER_NEXT(bif,
1541 struct bridge_iflist, bif_next) == NULL) 1542 struct bridge_iflist, bif_next) == NULL)
1542 { 1543 {
1543 used = true; 1544 used = true;
1544 mc = m; 1545 mc = m;
1545 } else { 1546 } else {
1546 mc = m_copym(m, 0, M_COPYALL, 1547 mc = m_copym(m, 0, M_COPYALL,
1547 M_DONTWAIT); 1548 M_DONTWAIT);
1548 if (mc == NULL) { 1549 if (mc == NULL) {
1549 sc->sc_if.if_oerrors++; 1550 sc->sc_if.if_oerrors++;
1550 goto next; 1551 goto next;
1551 } 1552 }
1552 } 1553 }
1553 1554
1554 m_set_rcvif(mc, dst_if); 1555 m_set_rcvif(mc, dst_if);
1555 mc->m_flags &= ~M_PROMISC; 1556 mc->m_flags &= ~M_PROMISC;
1556 1557
1557#ifndef NET_MPSAFE 1558#ifndef NET_MPSAFE
1558 s = splsoftnet(); 1559 s = splsoftnet();
1559#endif 1560#endif
1560 ether_input(dst_if, mc); 1561 ether_input(dst_if, mc);
1561#ifndef NET_MPSAFE 1562#ifndef NET_MPSAFE
1562 splx(s); 1563 splx(s);
1563#endif 1564#endif
1564 } 1565 }
1565 1566
1566next: 1567next:
1567 BRIDGE_PSZ_RENTER(s); 1568 BRIDGE_PSZ_RENTER(s);
1568 bridge_release_member(sc, bif, &psref); 1569 bridge_release_member(sc, bif, &psref);
1569 1570
1570 /* Guarantee we don't re-enter the loop as we already 1571 /* Guarantee we don't re-enter the loop as we already
1571 * decided we're at the end. */ 1572 * decided we're at the end. */
1572 if (used) 1573 if (used)
1573 break; 1574 break;
1574 } 1575 }
1575 BRIDGE_PSZ_REXIT(s); 1576 BRIDGE_PSZ_REXIT(s);
1576 1577
1577 if (!used) 1578 if (!used)
1578 m_freem(m); 1579 m_freem(m);
1579 return 0; 1580 return 0;
1580 } 1581 }
1581 1582
1582 sendunicast: 1583 sendunicast:
1583 /* 1584 /*
1584 * XXX Spanning tree consideration here? 1585 * XXX Spanning tree consideration here?
1585 */ 1586 */
1586 1587
1587 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1588 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1588 m_freem(m); 1589 m_freem(m);
1589 return 0; 1590 return 0;
1590 } 1591 }
1591 1592
1592 bridge_enqueue(sc, dst_if, m, 0); 1593 bridge_enqueue(sc, dst_if, m, 0);
1593 1594
1594 return 0; 1595 return 0;
1595} 1596}
1596 1597
1597/* 1598/*
1598 * bridge_start: 1599 * bridge_start:
1599 * 1600 *
1600 * Start output on a bridge. 1601 * Start output on a bridge.
1601 * 1602 *
1602 * NOTE: This routine should never be called in this implementation. 1603 * NOTE: This routine should never be called in this implementation.
1603 */ 1604 */
1604static void 1605static void
1605bridge_start(struct ifnet *ifp) 1606bridge_start(struct ifnet *ifp)
1606{ 1607{
1607 1608
1608 printf("%s: bridge_start() called\n", ifp->if_xname); 1609 printf("%s: bridge_start() called\n", ifp->if_xname);
1609} 1610}
1610 1611
1611/* 1612/*
1612 * bridge_forward: 1613 * bridge_forward:
1613 * 1614 *
1614 * The forwarding function of the bridge. 1615 * The forwarding function of the bridge.
1615 */ 1616 */
1616static void 1617static void
1617bridge_forward(struct bridge_softc *sc, struct mbuf *m) 1618bridge_forward(struct bridge_softc *sc, struct mbuf *m)
1618{ 1619{
1619 struct bridge_iflist *bif; 1620 struct bridge_iflist *bif;
1620 struct ifnet *src_if, *dst_if; 1621 struct ifnet *src_if, *dst_if;
1621 struct ether_header *eh; 1622 struct ether_header *eh;
1622 struct psref psref; 1623 struct psref psref;
1623 struct psref psref_src; 1624 struct psref psref_src;
1624 DECLARE_LOCK_VARIABLE; 1625 DECLARE_LOCK_VARIABLE;
1625 1626
1626 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) 1627 if ((sc->sc_if.if_flags & IFF_RUNNING) == 0)
1627 return; 1628 return;
1628 1629
1629 src_if = m_get_rcvif_psref(m, &psref_src); 1630 src_if = m_get_rcvif_psref(m, &psref_src);
1630 if (src_if == NULL) { 1631 if (src_if == NULL) {
1631 /* Interface is being destroyed? */ 1632 /* Interface is being destroyed? */
1632 m_freem(m); 1633 m_freem(m);
1633 goto out; 1634 goto out;
1634 } 1635 }
1635 1636
1636 sc->sc_if.if_ipackets++; 1637 sc->sc_if.if_ipackets++;
1637 sc->sc_if.if_ibytes += m->m_pkthdr.len; 1638 sc->sc_if.if_ibytes += m->m_pkthdr.len;
1638 1639
1639 /* 1640 /*
1640 * Look up the bridge_iflist. 1641 * Look up the bridge_iflist.
1641 */ 1642 */
1642 bif = bridge_lookup_member_if(sc, src_if, &psref); 1643 bif = bridge_lookup_member_if(sc, src_if, &psref);
1643 if (bif == NULL) { 1644 if (bif == NULL) {
1644 /* Interface is not a bridge member (anymore?) */ 1645 /* Interface is not a bridge member (anymore?) */
1645 m_freem(m); 1646 m_freem(m);
1646 goto out; 1647 goto out;
1647 } 1648 }
1648 1649
1649 if (bif->bif_flags & IFBIF_STP) { 1650 if (bif->bif_flags & IFBIF_STP) {
1650 switch (bif->bif_state) { 1651 switch (bif->bif_state) {
1651 case BSTP_IFSTATE_BLOCKING: 1652 case BSTP_IFSTATE_BLOCKING:
1652 case BSTP_IFSTATE_LISTENING: 1653 case BSTP_IFSTATE_LISTENING:
1653 case BSTP_IFSTATE_DISABLED: 1654 case BSTP_IFSTATE_DISABLED:
1654 m_freem(m); 1655 m_freem(m);
1655 bridge_release_member(sc, bif, &psref); 1656 bridge_release_member(sc, bif, &psref);
1656 goto out; 1657 goto out;
1657 } 1658 }
1658 } 1659 }
1659 1660
1660 eh = mtod(m, struct ether_header *); 1661 eh = mtod(m, struct ether_header *);
1661 1662
1662 /* 1663 /*
1663 * If the interface is learning, and the source 1664 * If the interface is learning, and the source
1664 * address is valid and not multicast, record 1665 * address is valid and not multicast, record
1665 * the address. 1666 * the address.
1666 */ 1667 */
1667 if ((bif->bif_flags & IFBIF_LEARNING) != 0 && 1668 if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
1668 ETHER_IS_MULTICAST(eh->ether_shost) == 0 && 1669 ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
1669 (eh->ether_shost[0] == 0 && 1670 (eh->ether_shost[0] == 0 &&
1670 eh->ether_shost[1] == 0 && 1671 eh->ether_shost[1] == 0 &&
1671 eh->ether_shost[2] == 0 && 1672 eh->ether_shost[2] == 0 &&
1672 eh->ether_shost[3] == 0 && 1673 eh->ether_shost[3] == 0 &&
1673 eh->ether_shost[4] == 0 && 1674 eh->ether_shost[4] == 0 &&
1674 eh->ether_shost[5] == 0) == 0) { 1675 eh->ether_shost[5] == 0) == 0) {
1675 (void) bridge_rtupdate(sc, eh->ether_shost, 1676 (void) bridge_rtupdate(sc, eh->ether_shost,
1676 src_if, 0, IFBAF_DYNAMIC); 1677 src_if, 0, IFBAF_DYNAMIC);
1677 } 1678 }
1678 1679
1679 if ((bif->bif_flags & IFBIF_STP) != 0 && 1680 if ((bif->bif_flags & IFBIF_STP) != 0 &&
1680 bif->bif_state == BSTP_IFSTATE_LEARNING) { 1681 bif->bif_state == BSTP_IFSTATE_LEARNING) {
1681 m_freem(m); 1682 m_freem(m);
1682 bridge_release_member(sc, bif, &psref); 1683 bridge_release_member(sc, bif, &psref);
1683 goto out; 1684 goto out;
1684 } 1685 }
1685 1686
1686 bridge_release_member(sc, bif, &psref); 1687 bridge_release_member(sc, bif, &psref);
1687 1688
1688 /* 1689 /*
1689 * At this point, the port either doesn't participate 1690 * At this point, the port either doesn't participate
1690 * in spanning tree or it is in the forwarding state. 1691 * in spanning tree or it is in the forwarding state.
1691 */ 1692 */
1692 1693
1693 /* 1694 /*
1694 * If the packet is unicast, destined for someone on 1695 * If the packet is unicast, destined for someone on
1695 * "this" side of the bridge, drop it. 1696 * "this" side of the bridge, drop it.
1696 */ 1697 */
1697 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { 1698 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
1698 dst_if = bridge_rtlookup(sc, eh->ether_dhost); 1699 dst_if = bridge_rtlookup(sc, eh->ether_dhost);
1699 if (src_if == dst_if) { 1700 if (src_if == dst_if) {
1700 m_freem(m); 1701 m_freem(m);
1701 goto out; 1702 goto out;
1702 } 1703 }
1703 } else { 1704 } else {
1704 /* ...forward it to all interfaces. */ 1705 /* ...forward it to all interfaces. */
1705 sc->sc_if.if_imcasts++; 1706 sc->sc_if.if_imcasts++;
1706 dst_if = NULL; 1707 dst_if = NULL;
1707 } 1708 }
1708 1709
1709 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, src_if, PFIL_IN) != 0) { 1710 if (pfil_run_hooks(sc->sc_if.if_pfil, &m, src_if, PFIL_IN) != 0) {
1710 if (m != NULL) 1711 if (m != NULL)
1711 m_freem(m); 1712 m_freem(m);
1712 goto out; 1713 goto out;
1713 } 1714 }
1714 if (m == NULL) 1715 if (m == NULL)
1715 goto out; 1716 goto out;
1716 1717
1717 if (dst_if == NULL) { 1718 if (dst_if == NULL) {
1718 bridge_broadcast(sc, src_if, m); 1719 bridge_broadcast(sc, src_if, m);
1719 goto out; 1720 goto out;
1720 } 1721 }
1721 1722
1722 m_put_rcvif_psref(src_if, &psref_src); 1723 m_put_rcvif_psref(src_if, &psref_src);
1723 src_if = NULL; 1724 src_if = NULL;
1724 1725
1725 /* 1726 /*
1726 * At this point, we're dealing with a unicast frame 1727 * At this point, we're dealing with a unicast frame
1727 * going to a different interface. 1728 * going to a different interface.
1728 */ 1729 */
1729 if ((dst_if->if_flags & IFF_RUNNING) == 0) { 1730 if ((dst_if->if_flags & IFF_RUNNING) == 0) {
1730 m_freem(m); 1731 m_freem(m);
1731 goto out; 1732 goto out;
1732 } 1733 }
1733 1734
1734 bif = bridge_lookup_member_if(sc, dst_if, &psref); 1735 bif = bridge_lookup_member_if(sc, dst_if, &psref);
1735 if (bif == NULL) { 1736 if (bif == NULL) {
1736 /* Not a member of the bridge (anymore?) */ 1737 /* Not a member of the bridge (anymore?) */
1737 m_freem(m); 1738 m_freem(m);
1738 goto out; 1739 goto out;
1739 } 1740 }
1740 1741
1741 if (bif->bif_flags & IFBIF_STP) { 1742 if (bif->bif_flags & IFBIF_STP) {
1742 switch (bif->bif_state) { 1743 switch (bif->bif_state) {
1743 case BSTP_IFSTATE_DISABLED: 1744 case BSTP_IFSTATE_DISABLED:
1744 case BSTP_IFSTATE_BLOCKING: 1745 case BSTP_IFSTATE_BLOCKING:
1745 m_freem(m); 1746 m_freem(m);
1746 bridge_release_member(sc, bif, &psref); 1747 bridge_release_member(sc, bif, &psref);
1747 goto out; 1748 goto out;
1748 } 1749 }
1749 } 1750 }
1750 1751
1751 bridge_release_member(sc, bif, &psref); 1752 bridge_release_member(sc, bif, &psref);
1752 1753
1753 ACQUIRE_GLOBAL_LOCKS(); 1754 ACQUIRE_GLOBAL_LOCKS();
1754 bridge_enqueue(sc, dst_if, m, 1); 1755 bridge_enqueue(sc, dst_if, m, 1);
1755 RELEASE_GLOBAL_LOCKS(); 1756 RELEASE_GLOBAL_LOCKS();
1756out: 1757out:
1757 if (src_if != NULL) 1758 if (src_if != NULL)
1758 m_put_rcvif_psref(src_if, &psref_src); 1759 m_put_rcvif_psref(src_if, &psref_src);
1759 return; 1760 return;
1760} 1761}
1761 1762
1762static bool 1763static bool
1763bstp_state_before_learning(struct bridge_iflist *bif) 1764bstp_state_before_learning(struct bridge_iflist *bif)
1764{ 1765{
1765 if (bif->bif_flags & IFBIF_STP) { 1766 if (bif->bif_flags & IFBIF_STP) {
1766 switch (bif->bif_state) { 1767 switch (bif->bif_state) {
1767 case BSTP_IFSTATE_BLOCKING: 1768 case BSTP_IFSTATE_BLOCKING:
1768 case BSTP_IFSTATE_LISTENING: 1769 case BSTP_IFSTATE_LISTENING:
1769 case BSTP_IFSTATE_DISABLED: 1770 case BSTP_IFSTATE_DISABLED:
1770 return true; 1771 return true;
1771 } 1772 }
1772 } 1773 }
1773 return false; 1774 return false;
1774} 1775}
1775 1776
1776static bool 1777static bool
1777bridge_ourether(struct bridge_iflist *bif, struct ether_header *eh, int src) 1778bridge_ourether(struct bridge_iflist *bif, struct ether_header *eh, int src)
1778{ 1779{
1779 uint8_t *ether = src ? eh->ether_shost : eh->ether_dhost; 1780 uint8_t *ether = src ? eh->ether_shost : eh->ether_dhost;
1780 1781
1781 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), ether, ETHER_ADDR_LEN) == 0 1782 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), ether, ETHER_ADDR_LEN) == 0
1782#if NCARP > 0 1783#if NCARP > 0
1783 || (bif->bif_ifp->if_carp && 1784 || (bif->bif_ifp->if_carp &&
1784 carp_ourether(bif->bif_ifp->if_carp, eh, IFT_ETHER, src) != NULL) 1785 carp_ourether(bif->bif_ifp->if_carp, eh, IFT_ETHER, src) != NULL)
1785#endif /* NCARP > 0 */ 1786#endif /* NCARP > 0 */
1786 ) 1787 )
1787 return true; 1788 return true;
1788 1789
1789 return false; 1790 return false;
1790} 1791}
1791 1792
1792/* 1793/*
1793 * bridge_input: 1794 * bridge_input:
1794 * 1795 *
1795 * Receive input from a member interface. Queue the packet for 1796 * Receive input from a member interface. Queue the packet for
1796 * bridging if it is not for us. 1797 * bridging if it is not for us.
1797 */ 1798 */
1798static void 1799static void
1799bridge_input(struct ifnet *ifp, struct mbuf *m) 1800bridge_input(struct ifnet *ifp, struct mbuf *m)
1800{ 1801{
1801 struct bridge_softc *sc = ifp->if_bridge; 1802 struct bridge_softc *sc = ifp->if_bridge;
1802 struct bridge_iflist *bif; 1803 struct bridge_iflist *bif;
1803 struct ether_header *eh; 1804 struct ether_header *eh;
1804 struct psref psref; 1805 struct psref psref;
1805 int bound; 1806 int bound;
1806 DECLARE_LOCK_VARIABLE; 1807 DECLARE_LOCK_VARIABLE;
1807 1808
1808 KASSERT(!cpu_intr_p()); 1809 KASSERT(!cpu_intr_p());
1809 1810
1810 if (__predict_false(sc == NULL) || 1811 if (__predict_false(sc == NULL) ||
1811 (sc->sc_if.if_flags & IFF_RUNNING) == 0) { 1812 (sc->sc_if.if_flags & IFF_RUNNING) == 0) {
1812 ACQUIRE_GLOBAL_LOCKS(); 1813 ACQUIRE_GLOBAL_LOCKS();
1813 ether_input(ifp, m); 1814 ether_input(ifp, m);
1814 RELEASE_GLOBAL_LOCKS(); 1815 RELEASE_GLOBAL_LOCKS();
1815 return; 1816 return;
1816 } 1817 }
1817 1818
1818 bound = curlwp_bind(); 1819 bound = curlwp_bind();
1819 bif = bridge_lookup_member_if(sc, ifp, &psref); 1820 bif = bridge_lookup_member_if(sc, ifp, &psref);
1820 if (bif == NULL) { 1821 if (bif == NULL) {
1821 curlwp_bindx(bound); 1822 curlwp_bindx(bound);
1822 ACQUIRE_GLOBAL_LOCKS(); 1823 ACQUIRE_GLOBAL_LOCKS();
1823 ether_input(ifp, m); 1824 ether_input(ifp, m);
1824 RELEASE_GLOBAL_LOCKS(); 1825 RELEASE_GLOBAL_LOCKS();
1825 return; 1826 return;
1826 } 1827 }
1827 1828
1828 eh = mtod(m, struct ether_header *); 1829 eh = mtod(m, struct ether_header *);
1829 1830
1830 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 1831 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
1831 if (memcmp(etherbroadcastaddr, 1832 if (memcmp(etherbroadcastaddr,
1832 eh->ether_dhost, ETHER_ADDR_LEN) == 0) 1833 eh->ether_dhost, ETHER_ADDR_LEN) == 0)
1833 m->m_flags |= M_BCAST; 1834 m->m_flags |= M_BCAST;
1834 else 1835 else
1835 m->m_flags |= M_MCAST; 1836 m->m_flags |= M_MCAST;
1836 } 1837 }
1837 1838
1838 /* 1839 /*
1839 * A 'fast' path for packets addressed to interfaces that are 1840 * A 'fast' path for packets addressed to interfaces that are
1840 * part of this bridge. 1841 * part of this bridge.
1841 */ 1842 */
1842 if (!(m->m_flags & (M_BCAST|M_MCAST)) && 1843 if (!(m->m_flags & (M_BCAST|M_MCAST)) &&
1843 !bstp_state_before_learning(bif)) { 1844 !bstp_state_before_learning(bif)) {
1844 struct bridge_iflist *_bif; 1845 struct bridge_iflist *_bif;
1845 struct ifnet *_ifp = NULL; 1846 struct ifnet *_ifp = NULL;
1846 int s; 1847 int s;
1847 struct psref _psref; 1848 struct psref _psref;
1848 1849
1849 BRIDGE_PSZ_RENTER(s); 1850 BRIDGE_PSZ_RENTER(s);
1850 BRIDGE_IFLIST_READER_FOREACH(_bif, sc) { 1851 BRIDGE_IFLIST_READER_FOREACH(_bif, sc) {
1851 /* It is destined for us. */ 1852 /* It is destined for us. */
1852 if (bridge_ourether(_bif, eh, 0)) { 1853 if (bridge_ourether(_bif, eh, 0)) {
1853 bridge_acquire_member(sc, _bif, &_psref); 1854 bridge_acquire_member(sc, _bif, &_psref);
1854 BRIDGE_PSZ_REXIT(s); 1855 BRIDGE_PSZ_REXIT(s);
1855 if (_bif->bif_flags & IFBIF_LEARNING) 1856 if (_bif->bif_flags & IFBIF_LEARNING)
1856 (void) bridge_rtupdate(sc, 1857 (void) bridge_rtupdate(sc,
1857 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC); 1858 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1858 m_set_rcvif(m, _bif->bif_ifp); 1859 m_set_rcvif(m, _bif->bif_ifp);
1859 _ifp = _bif->bif_ifp; 1860 _ifp = _bif->bif_ifp;
1860 bridge_release_member(sc, _bif, &_psref); 1861 bridge_release_member(sc, _bif, &_psref);
1861 goto out; 1862 goto out;
1862 } 1863 }
1863 1864
1864 /* We just received a packet that we sent out. */ 1865 /* We just received a packet that we sent out. */
1865 if (bridge_ourether(_bif, eh, 1)) 1866 if (bridge_ourether(_bif, eh, 1))
1866 break; 1867 break;
1867 } 1868 }
1868 BRIDGE_PSZ_REXIT(s); 1869 BRIDGE_PSZ_REXIT(s);
1869out: 1870out:
1870 1871
1871 if (_bif != NULL) { 1872 if (_bif != NULL) {
1872 bridge_release_member(sc, bif, &psref); 1873 bridge_release_member(sc, bif, &psref);
1873 curlwp_bindx(bound); 1874 curlwp_bindx(bound);
1874 if (_ifp != NULL) { 1875 if (_ifp != NULL) {
1875 m->m_flags &= ~M_PROMISC; 1876 m->m_flags &= ~M_PROMISC;
1876 ACQUIRE_GLOBAL_LOCKS(); 1877 ACQUIRE_GLOBAL_LOCKS();
1877 ether_input(_ifp, m); 1878 ether_input(_ifp, m);
1878 RELEASE_GLOBAL_LOCKS(); 1879 RELEASE_GLOBAL_LOCKS();
1879 } else 1880 } else
1880 m_freem(m); 1881 m_freem(m);
1881 return; 1882 return;
1882 } 1883 }
1883 } 1884 }
1884 1885
1885 /* Tap off 802.1D packets; they do not get forwarded. */ 1886 /* Tap off 802.1D packets; they do not get forwarded. */
1886 if (bif->bif_flags & IFBIF_STP && 1887 if (bif->bif_flags & IFBIF_STP &&
1887 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) { 1888 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) {
1888 bstp_input(sc, bif, m); 1889 bstp_input(sc, bif, m);
1889 bridge_release_member(sc, bif, &psref); 1890 bridge_release_member(sc, bif, &psref);
1890 curlwp_bindx(bound); 1891 curlwp_bindx(bound);
1891 return; 1892 return;
1892 } 1893 }
1893 1894
1894 /* 1895 /*
1895 * A normal switch would discard the packet here, but that's not what 1896 * A normal switch would discard the packet here, but that's not what
1896 * we've done historically. This also prevents some obnoxious behaviour. 1897 * we've done historically. This also prevents some obnoxious behaviour.
1897 */ 1898 */
1898 if (bstp_state_before_learning(bif)) { 1899 if (bstp_state_before_learning(bif)) {
1899 bridge_release_member(sc, bif, &psref); 1900 bridge_release_member(sc, bif, &psref);
1900 curlwp_bindx(bound); 1901 curlwp_bindx(bound);
1901 ACQUIRE_GLOBAL_LOCKS(); 1902 ACQUIRE_GLOBAL_LOCKS();
1902 ether_input(ifp, m); 1903 ether_input(ifp, m);
1903 RELEASE_GLOBAL_LOCKS(); 1904 RELEASE_GLOBAL_LOCKS();
1904 return; 1905 return;
1905 } 1906 }
1906 1907
1907 bridge_release_member(sc, bif, &psref); 1908 bridge_release_member(sc, bif, &psref);
1908 1909
1909 bridge_forward(sc, m); 1910 bridge_forward(sc, m);
1910 1911
1911 curlwp_bindx(bound); 1912 curlwp_bindx(bound);
1912} 1913}
1913 1914
1914/* 1915/*
1915 * bridge_broadcast: 1916 * bridge_broadcast:
1916 * 1917 *
1917 * Send a frame to all interfaces that are members of 1918 * Send a frame to all interfaces that are members of
1918 * the bridge, except for the one on which the packet 1919 * the bridge, except for the one on which the packet
1919 * arrived. 1920 * arrived.
1920 */ 1921 */
1921static void 1922static void
1922bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if, 1923bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
1923 struct mbuf *m) 1924 struct mbuf *m)
1924{ 1925{
1925 struct bridge_iflist *bif; 1926 struct bridge_iflist *bif;
1926 struct mbuf *mc; 1927 struct mbuf *mc;
1927 struct ifnet *dst_if; 1928 struct ifnet *dst_if;
1928 bool bmcast; 1929 bool bmcast;
1929 int s; 1930 int s;
1930 DECLARE_LOCK_VARIABLE; 1931 DECLARE_LOCK_VARIABLE;
1931 1932
1932 bmcast = m->m_flags & (M_BCAST|M_MCAST); 1933 bmcast = m->m_flags & (M_BCAST|M_MCAST);
1933 1934
1934 BRIDGE_PSZ_RENTER(s); 1935 BRIDGE_PSZ_RENTER(s);
1935 BRIDGE_IFLIST_READER_FOREACH(bif, sc) { 1936 BRIDGE_IFLIST_READER_FOREACH(bif, sc) {
1936 struct psref psref; 1937 struct psref psref;
1937 1938
1938 bridge_acquire_member(sc, bif, &psref); 1939 bridge_acquire_member(sc, bif, &psref);
1939 BRIDGE_PSZ_REXIT(s); 1940 BRIDGE_PSZ_REXIT(s);
1940 1941
1941 dst_if = bif->bif_ifp; 1942 dst_if = bif->bif_ifp;
1942 1943
1943 if (bif->bif_flags & IFBIF_STP) { 1944 if (bif->bif_flags & IFBIF_STP) {
1944 switch (bif->bif_state) { 1945 switch (bif->bif_state) {
1945 case BSTP_IFSTATE_BLOCKING: 1946 case BSTP_IFSTATE_BLOCKING:
1946 case BSTP_IFSTATE_DISABLED: 1947 case BSTP_IFSTATE_DISABLED:
1947 goto next; 1948 goto next;
1948 } 1949 }
1949 } 1950 }
1950 1951
1951 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast) 1952 if ((bif->bif_flags & IFBIF_DISCOVER) == 0 && !bmcast)
1952 goto next; 1953 goto next;
1953 1954
1954 if ((dst_if->if_flags & IFF_RUNNING) == 0) 1955 if ((dst_if->if_flags & IFF_RUNNING) == 0)
1955 goto next; 1956 goto next;
1956 1957
1957 if (dst_if != src_if) { 1958 if (dst_if != src_if) {
1958 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1959 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1959 if (mc == NULL) { 1960 if (mc == NULL) {
1960 sc->sc_if.if_oerrors++; 1961 sc->sc_if.if_oerrors++;
1961 goto next; 1962 goto next;
1962 } 1963 }
1963 ACQUIRE_GLOBAL_LOCKS(); 1964 ACQUIRE_GLOBAL_LOCKS();
1964 bridge_enqueue(sc, dst_if, mc, 1); 1965 bridge_enqueue(sc, dst_if, mc, 1);
1965 RELEASE_GLOBAL_LOCKS(); 1966 RELEASE_GLOBAL_LOCKS();
1966 } 1967 }
1967 1968
1968 if (bmcast) { 1969 if (bmcast) {
1969 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT); 1970 mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
1970 if (mc == NULL) { 1971 if (mc == NULL) {
1971 sc->sc_if.if_oerrors++; 1972 sc->sc_if.if_oerrors++;
1972 goto next; 1973 goto next;
1973 } 1974 }
1974 1975
1975 m_set_rcvif(mc, dst_if); 1976 m_set_rcvif(mc, dst_if);
1976 mc->m_flags &= ~M_PROMISC; 1977 mc->m_flags &= ~M_PROMISC;
1977 1978
1978 ACQUIRE_GLOBAL_LOCKS(); 1979 ACQUIRE_GLOBAL_LOCKS();
1979 ether_input(dst_if, mc); 1980 ether_input(dst_if, mc);
1980 RELEASE_GLOBAL_LOCKS(); 1981 RELEASE_GLOBAL_LOCKS();
1981 } 1982 }
1982next: 1983next:
1983 BRIDGE_PSZ_RENTER(s); 1984 BRIDGE_PSZ_RENTER(s);
1984 bridge_release_member(sc, bif, &psref); 1985 bridge_release_member(sc, bif, &psref);
1985 } 1986 }
1986 BRIDGE_PSZ_REXIT(s); 1987 BRIDGE_PSZ_REXIT(s);
1987 1988
1988 m_freem(m); 1989 m_freem(m);
1989} 1990}
1990 1991
1991static int 1992static int
1992bridge_rtalloc(struct bridge_softc *sc, const uint8_t *dst, 1993bridge_rtalloc(struct bridge_softc *sc, const uint8_t *dst,
1993 struct bridge_rtnode **brtp) 1994 struct bridge_rtnode **brtp)
1994{ 1995{
1995 struct bridge_rtnode *brt; 1996 struct bridge_rtnode *brt;
1996 int error; 1997 int error;
1997 1998
1998 if (sc->sc_brtcnt >= sc->sc_brtmax) 1999 if (sc->sc_brtcnt >= sc->sc_brtmax)
1999 return ENOSPC; 2000 return ENOSPC;
2000 2001
2001 /* 2002 /*
2002 * Allocate a new bridge forwarding node, and 2003 * Allocate a new bridge forwarding node, and
2003 * initialize the expiration time and Ethernet 2004 * initialize the expiration time and Ethernet
2004 * address. 2005 * address.
2005 */ 2006 */
2006 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT); 2007 brt = pool_get(&bridge_rtnode_pool, PR_NOWAIT);
2007 if (brt == NULL) 2008 if (brt == NULL)
2008 return ENOMEM; 2009 return ENOMEM;
2009 2010
2010 memset(brt, 0, sizeof(*brt)); 2011 memset(brt, 0, sizeof(*brt));
2011 brt->brt_expire = time_uptime + sc->sc_brttimeout; 2012 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2012 brt->brt_flags = IFBAF_DYNAMIC; 2013 brt->brt_flags = IFBAF_DYNAMIC;
2013 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); 2014 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN);
2014 2015
2015 BRIDGE_RT_LOCK(sc); 2016 BRIDGE_RT_LOCK(sc);
2016 error = bridge_rtnode_insert(sc, brt); 2017 error = bridge_rtnode_insert(sc, brt);
2017 BRIDGE_RT_UNLOCK(sc); 2018 BRIDGE_RT_UNLOCK(sc);
2018 2019
2019 if (error != 0) { 2020 if (error != 0) {
2020 pool_put(&bridge_rtnode_pool, brt); 2021 pool_put(&bridge_rtnode_pool, brt);
2021 return error; 2022 return error;
2022 } 2023 }
2023 2024
2024 *brtp = brt; 2025 *brtp = brt;
2025 return 0; 2026 return 0;
2026} 2027}
2027 2028
2028/* 2029/*
2029 * bridge_rtupdate: 2030 * bridge_rtupdate:
2030 * 2031 *
2031 * Add a bridge routing entry. 2032 * Add a bridge routing entry.
2032 */ 2033 */
2033static int 2034static int
2034bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst, 2035bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
2035 struct ifnet *dst_if, int setflags, uint8_t flags) 2036 struct ifnet *dst_if, int setflags, uint8_t flags)
2036{ 2037{
2037 struct bridge_rtnode *brt; 2038 struct bridge_rtnode *brt;
2038 int s; 2039 int s;
2039 2040
2040again: 2041again:
2041 /* 2042 /*
2042 * A route for this destination might already exist. If so, 2043 * A route for this destination might already exist. If so,
2043 * update it, otherwise create a new one. 2044 * update it, otherwise create a new one.
2044 */ 2045 */
2045 BRIDGE_RT_RENTER(s); 2046 BRIDGE_RT_RENTER(s);
2046 brt = bridge_rtnode_lookup(sc, dst); 2047 brt = bridge_rtnode_lookup(sc, dst);
2047 2048
2048 if (brt != NULL) { 2049 if (brt != NULL) {
2049 brt->brt_ifp = dst_if; 2050 brt->brt_ifp = dst_if;
2050 if (setflags) { 2051 if (setflags) {
2051 brt->brt_flags = flags; 2052 brt->brt_flags = flags;
2052 if (flags & IFBAF_STATIC) 2053 if (flags & IFBAF_STATIC)
2053 brt->brt_expire = 0; 2054 brt->brt_expire = 0;
2054 else 2055 else
2055 brt->brt_expire = time_uptime + sc->sc_brttimeout; 2056 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2056 } else { 2057 } else {
2057 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 2058 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2058 brt->brt_expire = time_uptime + sc->sc_brttimeout; 2059 brt->brt_expire = time_uptime + sc->sc_brttimeout;
2059 } 2060 }
2060 } 2061 }
2061 BRIDGE_RT_REXIT(s); 2062 BRIDGE_RT_REXIT(s);
2062 2063
2063 if (brt == NULL) { 2064 if (brt == NULL) {
2064 int r; 2065 int r;
2065 2066
2066 r = bridge_rtalloc(sc, dst, &brt); 2067 r = bridge_rtalloc(sc, dst, &brt);
2067 if (r != 0) 2068 if (r != 0)
2068 return r; 2069 return r;
2069 goto again; 2070 goto again;
2070 } 2071 }
2071 2072
2072 return 0; 2073 return 0;
2073} 2074}
2074 2075
2075/* 2076/*
2076 * bridge_rtlookup: 2077 * bridge_rtlookup:
2077 * 2078 *
2078 * Lookup the destination interface for an address. 2079 * Lookup the destination interface for an address.
2079 */ 2080 */
2080static struct ifnet * 2081static struct ifnet *
2081bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr) 2082bridge_rtlookup(struct bridge_softc *sc, const uint8_t *addr)
2082{ 2083{
2083 struct bridge_rtnode *brt; 2084 struct bridge_rtnode *brt;
2084 struct ifnet *ifs = NULL; 2085 struct ifnet *ifs = NULL;
2085 int s; 2086 int s;
2086 2087
2087 BRIDGE_RT_RENTER(s); 2088 BRIDGE_RT_RENTER(s);
2088 brt = bridge_rtnode_lookup(sc, addr); 2089 brt = bridge_rtnode_lookup(sc, addr);
2089 if (brt != NULL) 2090 if (brt != NULL)
2090 ifs = brt->brt_ifp; 2091 ifs = brt->brt_ifp;
2091 BRIDGE_RT_REXIT(s); 2092 BRIDGE_RT_REXIT(s);
2092 2093
2093 return ifs; 2094 return ifs;
2094} 2095}
2095 2096
2096typedef bool (*bridge_iterate_cb_t) 2097typedef bool (*bridge_iterate_cb_t)
2097 (struct bridge_softc *, struct bridge_rtnode *, bool *, void *); 2098 (struct bridge_softc *, struct bridge_rtnode *, bool *, void *);
2098 2099
2099/* 2100/*
2100 * bridge_rtlist_iterate_remove: 2101 * bridge_rtlist_iterate_remove:
2101 * 2102 *
2102 * It iterates on sc->sc_rtlist and removes rtnodes of it which func 2103 * It iterates on sc->sc_rtlist and removes rtnodes of it which func
2103 * callback judges to remove. Removals of rtnodes are done in a manner 2104 * callback judges to remove. Removals of rtnodes are done in a manner
2104 * of pserialize. To this end, all kmem_* operations are placed out of 2105 * of pserialize. To this end, all kmem_* operations are placed out of
2105 * mutexes. 2106 * mutexes.
2106 */ 2107 */
2107static void 2108static void
2108bridge_rtlist_iterate_remove(struct bridge_softc *sc, bridge_iterate_cb_t func, void *arg) 2109bridge_rtlist_iterate_remove(struct bridge_softc *sc, bridge_iterate_cb_t func, void *arg)
2109{ 2110{
2110 struct bridge_rtnode *brt, *nbrt; 2111 struct bridge_rtnode *brt, *nbrt;
2111 struct bridge_rtnode **brt_list; 2112 struct bridge_rtnode **brt_list;
2112 int i, count; 2113 int i, count;
2113 2114
2114retry: 2115retry:
2115 count = sc->sc_brtcnt; 2116 count = sc->sc_brtcnt;
2116 if (count == 0) 2117 if (count == 0)
2117 return; 2118 return;
2118 brt_list = kmem_alloc(sizeof(*brt_list) * count, KM_SLEEP); 2119 brt_list = kmem_alloc(sizeof(*brt_list) * count, KM_SLEEP);
2119 2120
2120 BRIDGE_RT_LOCK(sc); 2121 BRIDGE_RT_LOCK(sc);
2121 if (__predict_false(sc->sc_brtcnt > count)) { 2122 if (__predict_false(sc->sc_brtcnt > count)) {
2122 /* The rtnodes increased, we need more memory */ 2123 /* The rtnodes increased, we need more memory */
2123 BRIDGE_RT_UNLOCK(sc); 2124 BRIDGE_RT_UNLOCK(sc);
2124 kmem_free(brt_list, sizeof(*brt_list) * count); 2125 kmem_free(brt_list, sizeof(*brt_list) * count);
2125 goto retry; 2126 goto retry;
2126 } 2127 }
2127 2128
2128 i = 0; 2129 i = 0;
2129 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { 2130 LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
2130 bool need_break = false; 2131 bool need_break = false;
2131 if (func(sc, brt, &need_break, arg)) { 2132 if (func(sc, brt, &need_break, arg)) {
2132 bridge_rtnode_remove(sc, brt); 2133 bridge_rtnode_remove(sc, brt);
2133 brt_list[i++] = brt; 2134 brt_list[i++] = brt;
2134 } 2135 }
2135 if (need_break) 2136 if (need_break)
2136 break; 2137 break;
2137 } 2138 }
2138 2139
2139 if (i > 0) 2140 if (i > 0)
2140 BRIDGE_RT_PSZ_PERFORM(sc); 2141 BRIDGE_RT_PSZ_PERFORM(sc);
2141 BRIDGE_RT_UNLOCK(sc); 2142 BRIDGE_RT_UNLOCK(sc);
2142 2143
2143 while (--i >= 0) 2144 while (--i >= 0)
2144 bridge_rtnode_destroy(brt_list[i]); 2145 bridge_rtnode_destroy(brt_list[i]);
2145 2146
2146 kmem_free(brt_list, sizeof(*brt_list) * count); 2147 kmem_free(brt_list, sizeof(*brt_list) * count);
2147} 2148}
2148 2149
2149static bool 2150static bool
2150bridge_rttrim0_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2151bridge_rttrim0_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2151 bool *need_break, void *arg) 2152 bool *need_break, void *arg)
2152{ 2153{
2153 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { 2154 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
2154 /* Take into account of the subsequent removal */ 2155 /* Take into account of the subsequent removal */
2155 if ((sc->sc_brtcnt - 1) <= sc->sc_brtmax) 2156 if ((sc->sc_brtcnt - 1) <= sc->sc_brtmax)
2156 *need_break = true; 2157 *need_break = true;
2157 return true; 2158 return true;
2158 } else 2159 } else
2159 return false; 2160 return false;
2160} 2161}
2161 2162
2162static void 2163static void
2163bridge_rttrim0(struct bridge_softc *sc) 2164bridge_rttrim0(struct bridge_softc *sc)
2164{ 2165{
2165 bridge_rtlist_iterate_remove(sc, bridge_rttrim0_cb, NULL); 2166 bridge_rtlist_iterate_remove(sc, bridge_rttrim0_cb, NULL);
2166} 2167}
2167 2168
2168/* 2169/*
2169 * bridge_rttrim: 2170 * bridge_rttrim:
2170 * 2171 *
2171 * Trim the routine table so that we have a number 2172 * Trim the routine table so that we have a number
2172 * of routing entries less than or equal to the 2173 * of routing entries less than or equal to the
2173 * maximum number. 2174 * maximum number.
2174 */ 2175 */
2175static void 2176static void
2176bridge_rttrim(struct bridge_softc *sc) 2177bridge_rttrim(struct bridge_softc *sc)
2177{ 2178{
2178 2179
2179 /* Make sure we actually need to do this. */ 2180 /* Make sure we actually need to do this. */
2180 if (sc->sc_brtcnt <= sc->sc_brtmax) 2181 if (sc->sc_brtcnt <= sc->sc_brtmax)
2181 return; 2182 return;
2182 2183
2183 /* Force an aging cycle; this might trim enough addresses. */ 2184 /* Force an aging cycle; this might trim enough addresses. */
2184 bridge_rtage(sc); 2185 bridge_rtage(sc);
2185 if (sc->sc_brtcnt <= sc->sc_brtmax) 2186 if (sc->sc_brtcnt <= sc->sc_brtmax)
2186 return; 2187 return;
2187 2188
2188 bridge_rttrim0(sc); 2189 bridge_rttrim0(sc);
2189 2190
2190 return; 2191 return;
2191} 2192}
2192 2193
2193/* 2194/*
2194 * bridge_timer: 2195 * bridge_timer:
2195 * 2196 *
2196 * Aging timer for the bridge. 2197 * Aging timer for the bridge.
2197 */ 2198 */
2198static void 2199static void
2199bridge_timer(void *arg) 2200bridge_timer(void *arg)
2200{ 2201{
2201 struct bridge_softc *sc = arg; 2202 struct bridge_softc *sc = arg;
2202 2203
2203 workqueue_enqueue(sc->sc_rtage_wq, &sc->sc_rtage_wk, NULL); 2204 workqueue_enqueue(sc->sc_rtage_wq, &sc->sc_rtage_wk, NULL);
2204} 2205}
2205 2206
2206static void 2207static void
2207bridge_rtage_work(struct work *wk, void *arg) 2208bridge_rtage_work(struct work *wk, void *arg)
2208{ 2209{
2209 struct bridge_softc *sc = arg; 2210 struct bridge_softc *sc = arg;
2210 2211
2211 KASSERT(wk == &sc->sc_rtage_wk); 2212 KASSERT(wk == &sc->sc_rtage_wk);
2212 2213
2213 bridge_rtage(sc); 2214 bridge_rtage(sc);
2214 2215
2215 if (sc->sc_if.if_flags & IFF_RUNNING) 2216 if (sc->sc_if.if_flags & IFF_RUNNING)
2216 callout_reset(&sc->sc_brcallout, 2217 callout_reset(&sc->sc_brcallout,
2217 bridge_rtable_prune_period * hz, bridge_timer, sc); 2218 bridge_rtable_prune_period * hz, bridge_timer, sc);
2218} 2219}
2219 2220
2220static bool 2221static bool
2221bridge_rtage_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2222bridge_rtage_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2222 bool *need_break, void *arg) 2223 bool *need_break, void *arg)
2223{ 2224{
2224 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && 2225 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC &&
2225 time_uptime >= brt->brt_expire) 2226 time_uptime >= brt->brt_expire)
2226 return true; 2227 return true;
2227 else 2228 else
2228 return false; 2229 return false;
2229} 2230}
2230 2231
2231/* 2232/*
2232 * bridge_rtage: 2233 * bridge_rtage:
2233 * 2234 *
2234 * Perform an aging cycle. 2235 * Perform an aging cycle.
2235 */ 2236 */
2236static void 2237static void
2237bridge_rtage(struct bridge_softc *sc) 2238bridge_rtage(struct bridge_softc *sc)
2238{ 2239{
2239 bridge_rtlist_iterate_remove(sc, bridge_rtage_cb, NULL); 2240 bridge_rtlist_iterate_remove(sc, bridge_rtage_cb, NULL);
2240} 2241}
2241 2242
2242 2243
2243static bool 2244static bool
2244bridge_rtflush_cb(struct bridge_softc *sc, struct bridge_rtnode *brt, 2245bridge_rtflush_cb(struct bridge_softc *sc, struct bridge_rtnode *brt,
2245 bool *need_break, void *arg) 2246 bool *need_break, void *arg)
2246{ 2247{
2247 int full = *(int*)arg; 2248 int full = *(int*)arg;
2248 2249
2249 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) 2250 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
2250 return true; 2251 return true;
2251 else 2252 else
2252 return false; 2253 return false;
2253} 2254}
2254 2255
2255/* 2256/*
2256 * bridge_rtflush: 2257 * bridge_rtflush:
2257 * 2258 *
2258 * Remove all dynamic addresses from the bridge. 2259 * Remove all dynamic addresses from the bridge.
2259 */ 2260 */
2260static void 2261static void
2261bridge_rtflush(struct bridge_softc *sc, int full) 2262bridge_rtflush(struct bridge_softc *sc, int full)
2262{ 2263{
2263 bridge_rtlist_iterate_remove(sc, bridge_rtflush_cb, &full); 2264 bridge_rtlist_iterate_remove(sc, bridge_rtflush_cb, &full);
2264} 2265}
2265 2266
2266/* 2267/*
2267 * bridge_rtdaddr: 2268 * bridge_rtdaddr:
2268 * 2269 *
2269 * Remove an address from the table. 2270 * Remove an address from the table.
2270 */ 2271 */
2271static int 2272static int
2272bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr) 2273bridge_rtdaddr(struct bridge_softc *sc, const uint8_t *addr)
2273{ 2274{
2274 struct bridge_rtnode *brt; 2275 struct bridge_rtnode *brt;
2275 2276
2276 BRIDGE_RT_LOCK(sc); 2277 BRIDGE_RT_LOCK(sc);
2277 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) { 2278 if ((brt = bridge_rtnode_lookup(sc, addr)) == NULL) {
2278 BRIDGE_RT_UNLOCK(sc); 2279 BRIDGE_RT_UNLOCK(sc);
2279 return ENOENT; 2280 return ENOENT;
2280 } 2281 }
2281 bridge_rtnode_remove(sc, brt); 2282 bridge_rtnode_remove(sc, brt);
2282 BRIDGE_RT_PSZ_PERFORM(sc); 2283 BRIDGE_RT_PSZ_PERFORM(sc);
2283 BRIDGE_RT_UNLOCK(sc); 2284 BRIDGE_RT_UNLOCK(sc);
2284 2285
2285 bridge_rtnode_destroy(brt); 2286 bridge_rtnode_destroy(brt);
2286 2287
2287 return 0; 2288 return 0;
2288} 2289}
2289 2290
2290/* 2291/*
2291 * bridge_rtdelete: 2292 * bridge_rtdelete:
2292 * 2293 *
2293 * Delete routes to a speicifc member interface. 2294 * Delete routes to a speicifc member interface.
2294 */ 2295 */
2295static void 2296static void
2296bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp) 2297bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp)
2297{ 2298{
2298 struct bridge_rtnode *brt; 2299 struct bridge_rtnode *brt;
2299 2300
2300 BRIDGE_RT_LOCK(sc); 2301 BRIDGE_RT_LOCK(sc);
2301 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { 2302 LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
2302 if (brt->brt_ifp == ifp) 2303 if (brt->brt_ifp == ifp)
2303 break; 2304 break;
2304 } 2305 }
2305 if (brt == NULL) { 2306 if (brt == NULL) {
2306 BRIDGE_RT_UNLOCK(sc); 2307 BRIDGE_RT_UNLOCK(sc);
2307 return; 2308 return;
2308 } 2309 }
2309 bridge_rtnode_remove(sc, brt); 2310 bridge_rtnode_remove(sc, brt);
2310 BRIDGE_RT_PSZ_PERFORM(sc); 2311 BRIDGE_RT_PSZ_PERFORM(sc);
2311 BRIDGE_RT_UNLOCK(sc); 2312 BRIDGE_RT_UNLOCK(sc);
2312 2313
2313 bridge_rtnode_destroy(brt); 2314 bridge_rtnode_destroy(brt);
2314} 2315}
2315 2316
2316/* 2317/*
2317 * bridge_rtable_init: 2318 * bridge_rtable_init:
2318 * 2319 *
2319 * Initialize the route table for this bridge. 2320 * Initialize the route table for this bridge.
2320 */ 2321 */
2321static void 2322static void
2322bridge_rtable_init(struct bridge_softc *sc) 2323bridge_rtable_init(struct bridge_softc *sc)
2323{ 2324{
2324 int i; 2325 int i;
2325 2326
2326 sc->sc_rthash = kmem_alloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, 2327 sc->sc_rthash = kmem_alloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE,
2327 KM_SLEEP); 2328 KM_SLEEP);
2328 2329
2329 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++) 2330 for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
2330 LIST_INIT(&sc->sc_rthash[i]); 2331 LIST_INIT(&sc->sc_rthash[i]);
2331 2332
2332 sc->sc_rthash_key = cprng_fast32(); 2333 sc->sc_rthash_key = cprng_fast32();
2333 2334
2334 LIST_INIT(&sc->sc_rtlist); 2335 LIST_INIT(&sc->sc_rtlist);
2335 2336
2336 sc->sc_rtlist_psz = pserialize_create(); 2337 sc->sc_rtlist_psz = pserialize_create();
2337 sc->sc_rtlist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 2338 sc->sc_rtlist_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
2338} 2339}
2339 2340
2340/* 2341/*
2341 * bridge_rtable_fini: 2342 * bridge_rtable_fini:
2342 * 2343 *
2343 * Deconstruct the route table for this bridge. 2344 * Deconstruct the route table for this bridge.
2344 */ 2345 */
2345static void 2346static void
2346bridge_rtable_fini(struct bridge_softc *sc) 2347bridge_rtable_fini(struct bridge_softc *sc)
2347{ 2348{
2348 2349
2349 kmem_free(sc->sc_rthash, sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE); 2350 kmem_free(sc->sc_rthash, sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE);
2350 if (sc->sc_rtlist_lock) 2351 if (sc->sc_rtlist_lock)
2351 mutex_obj_free(sc->sc_rtlist_lock); 2352 mutex_obj_free(sc->sc_rtlist_lock);
2352 if (sc->sc_rtlist_psz) 2353 if (sc->sc_rtlist_psz)
2353 pserialize_destroy(sc->sc_rtlist_psz); 2354 pserialize_destroy(sc->sc_rtlist_psz);
2354} 2355}
2355 2356
2356/* 2357/*
2357 * The following hash function is adapted from "Hash Functions" by Bob Jenkins 2358 * The following hash function is adapted from "Hash Functions" by Bob Jenkins
2358 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997). 2359 * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
2359 */ 2360 */
2360#define mix(a, b, c) \ 2361#define mix(a, b, c) \

cvs diff -r1.177 -r1.178 src/sys/net/if_spppsubr.c (switch to unified diff)

--- src/sys/net/if_spppsubr.c 2017/12/11 03:29:20 1.177
+++ src/sys/net/if_spppsubr.c 2017/12/28 07:06:36 1.178
@@ -1,2074 +1,2075 @@ @@ -1,2074 +1,2075 @@
1/* $NetBSD: if_spppsubr.c,v 1.177 2017/12/11 03:29:20 ozaki-r Exp $ */ 1/* $NetBSD: if_spppsubr.c,v 1.178 2017/12/28 07:06:36 ozaki-r Exp $ */
2 2
3/* 3/*
4 * Synchronous PPP/Cisco link level subroutines. 4 * Synchronous PPP/Cisco link level subroutines.
5 * Keepalive protocol implemented in both Cisco and PPP modes. 5 * Keepalive protocol implemented in both Cisco and PPP modes.
6 * 6 *
7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd. 7 * Copyright (C) 1994-1996 Cronyx Engineering Ltd.
8 * Author: Serge Vakulenko, <vak@cronyx.ru> 8 * Author: Serge Vakulenko, <vak@cronyx.ru>
9 * 9 *
10 * Heavily revamped to conform to RFC 1661. 10 * Heavily revamped to conform to RFC 1661.
11 * Copyright (C) 1997, Joerg Wunsch. 11 * Copyright (C) 1997, Joerg Wunsch.
12 * 12 *
13 * RFC2472 IPv6CP support. 13 * RFC2472 IPv6CP support.
14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>. 14 * Copyright (C) 2000, Jun-ichiro itojun Hagino <itojun@iijlab.net>.
15 * 15 *
16 * Redistribution and use in source and binary forms, with or without 16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions are met: 17 * modification, are permitted provided that the following conditions are met:
18 * 1. Redistributions of source code must retain the above copyright notice, 18 * 1. Redistributions of source code must retain the above copyright notice,
19 * this list of conditions and the following disclaimer. 19 * this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright notice, 20 * 2. Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation 21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials provided with the distribution. 22 * and/or other materials provided with the distribution.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY 24 * THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY
25 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE. 34 * POSSIBILITY OF SUCH DAMAGE.
35 * 35 *
36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997 36 * From: Version 2.4, Thu Apr 30 17:17:21 MSD 1997
37 * 37 *
38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp 38 * From: if_spppsubr.c,v 1.39 1998/04/04 13:26:03 phk Exp
39 * 39 *
40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp 40 * From: Id: if_spppsubr.c,v 1.23 1999/02/23 14:47:50 hm Exp
41 */ 41 */
42 42
43#include <sys/cdefs.h> 43#include <sys/cdefs.h>
44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.177 2017/12/11 03:29:20 ozaki-r Exp $"); 44__KERNEL_RCSID(0, "$NetBSD: if_spppsubr.c,v 1.178 2017/12/28 07:06:36 ozaki-r Exp $");
45 45
46#if defined(_KERNEL_OPT) 46#if defined(_KERNEL_OPT)
47#include "opt_inet.h" 47#include "opt_inet.h"
48#include "opt_modular.h" 48#include "opt_modular.h"
49#include "opt_compat_netbsd.h" 49#include "opt_compat_netbsd.h"
50#include "opt_net_mpsafe.h" 50#include "opt_net_mpsafe.h"
51#endif 51#endif
52 52
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/proc.h> 55#include <sys/proc.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/kernel.h> 57#include <sys/kernel.h>
58#include <sys/sockio.h> 58#include <sys/sockio.h>
59#include <sys/socket.h> 59#include <sys/socket.h>
60#include <sys/syslog.h> 60#include <sys/syslog.h>
61#include <sys/malloc.h> 61#include <sys/malloc.h>
62#include <sys/mbuf.h> 62#include <sys/mbuf.h>
63#include <sys/callout.h> 63#include <sys/callout.h>
64#include <sys/md5.h> 64#include <sys/md5.h>
65#include <sys/inttypes.h> 65#include <sys/inttypes.h>
66#include <sys/kauth.h> 66#include <sys/kauth.h>
67#include <sys/cprng.h> 67#include <sys/cprng.h>
68#include <sys/module.h> 68#include <sys/module.h>
69#include <sys/workqueue.h> 69#include <sys/workqueue.h>
70#include <sys/atomic.h> 70#include <sys/atomic.h>
71 71
72#include <net/if.h> 72#include <net/if.h>
73#include <net/netisr.h> 73#include <net/netisr.h>
74#include <net/if_types.h> 74#include <net/if_types.h>
75#include <net/route.h> 75#include <net/route.h>
76#include <net/ppp_defs.h> 76#include <net/ppp_defs.h>
77 77
78#include <netinet/in.h> 78#include <netinet/in.h>
79#include <netinet/in_systm.h> 79#include <netinet/in_systm.h>
80#include <netinet/in_var.h> 80#include <netinet/in_var.h>
81#ifdef INET 81#ifdef INET
82#include <netinet/ip.h> 82#include <netinet/ip.h>
83#include <netinet/tcp.h> 83#include <netinet/tcp.h>
84#endif 84#endif
85#include <net/ethertypes.h> 85#include <net/ethertypes.h>
86 86
87#ifdef INET6 87#ifdef INET6
88#include <netinet6/scope6_var.h> 88#include <netinet6/scope6_var.h>
89#endif 89#endif
90 90
91#include <net/if_sppp.h> 91#include <net/if_sppp.h>
92#include <net/if_spppvar.h> 92#include <net/if_spppvar.h>
93 93
94#ifdef NET_MPSAFE 94#ifdef NET_MPSAFE
95#define SPPPSUBR_MPSAFE 1 95#define SPPPSUBR_MPSAFE 1
96#endif 96#endif
97 97
98#define LCP_KEEPALIVE_INTERVAL 10 /* seconds between checks */ 98#define LCP_KEEPALIVE_INTERVAL 10 /* seconds between checks */
99#define LOOPALIVECNT 3 /* loopback detection tries */ 99#define LOOPALIVECNT 3 /* loopback detection tries */
100#define DEFAULT_MAXALIVECNT 3 /* max. missed alive packets */ 100#define DEFAULT_MAXALIVECNT 3 /* max. missed alive packets */
101#define DEFAULT_NORECV_TIME 15 /* before we get worried */ 101#define DEFAULT_NORECV_TIME 15 /* before we get worried */
102#define DEFAULT_MAX_AUTH_FAILURES 5 /* max. auth. failures */ 102#define DEFAULT_MAX_AUTH_FAILURES 5 /* max. auth. failures */
103 103
104/* 104/*
105 * Interface flags that can be set in an ifconfig command. 105 * Interface flags that can be set in an ifconfig command.
106 * 106 *
107 * Setting link0 will make the link passive, i.e. it will be marked 107 * Setting link0 will make the link passive, i.e. it will be marked
108 * as being administrative openable, but won't be opened to begin 108 * as being administrative openable, but won't be opened to begin
109 * with. Incoming calls will be answered, or subsequent calls with 109 * with. Incoming calls will be answered, or subsequent calls with
110 * -link1 will cause the administrative open of the LCP layer. 110 * -link1 will cause the administrative open of the LCP layer.
111 * 111 *
112 * Setting link1 will cause the link to auto-dial only as packets 112 * Setting link1 will cause the link to auto-dial only as packets
113 * arrive to be sent. 113 * arrive to be sent.
114 * 114 *
115 * Setting IFF_DEBUG will syslog the option negotiation and state 115 * Setting IFF_DEBUG will syslog the option negotiation and state
116 * transitions at level kern.debug. Note: all logs consistently look 116 * transitions at level kern.debug. Note: all logs consistently look
117 * like 117 * like
118 * 118 *
119 * <if-name><unit>: <proto-name> <additional info...> 119 * <if-name><unit>: <proto-name> <additional info...>
120 * 120 *
121 * with <if-name><unit> being something like "bppp0", and <proto-name> 121 * with <if-name><unit> being something like "bppp0", and <proto-name>
122 * being one of "lcp", "ipcp", "cisco", "chap", "pap", etc. 122 * being one of "lcp", "ipcp", "cisco", "chap", "pap", etc.
123 */ 123 */
124 124
125#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ 125#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */
126#define IFF_AUTO IFF_LINK1 /* auto-dial on output */ 126#define IFF_AUTO IFF_LINK1 /* auto-dial on output */
127 127
128#define CONF_REQ 1 /* PPP configure request */ 128#define CONF_REQ 1 /* PPP configure request */
129#define CONF_ACK 2 /* PPP configure acknowledge */ 129#define CONF_ACK 2 /* PPP configure acknowledge */
130#define CONF_NAK 3 /* PPP configure negative ack */ 130#define CONF_NAK 3 /* PPP configure negative ack */
131#define CONF_REJ 4 /* PPP configure reject */ 131#define CONF_REJ 4 /* PPP configure reject */
132#define TERM_REQ 5 /* PPP terminate request */ 132#define TERM_REQ 5 /* PPP terminate request */
133#define TERM_ACK 6 /* PPP terminate acknowledge */ 133#define TERM_ACK 6 /* PPP terminate acknowledge */
134#define CODE_REJ 7 /* PPP code reject */ 134#define CODE_REJ 7 /* PPP code reject */
135#define PROTO_REJ 8 /* PPP protocol reject */ 135#define PROTO_REJ 8 /* PPP protocol reject */
136#define ECHO_REQ 9 /* PPP echo request */ 136#define ECHO_REQ 9 /* PPP echo request */
137#define ECHO_REPLY 10 /* PPP echo reply */ 137#define ECHO_REPLY 10 /* PPP echo reply */
138#define DISC_REQ 11 /* PPP discard request */ 138#define DISC_REQ 11 /* PPP discard request */
139 139
140#define LCP_OPT_MRU 1 /* maximum receive unit */ 140#define LCP_OPT_MRU 1 /* maximum receive unit */
141#define LCP_OPT_ASYNC_MAP 2 /* async control character map */ 141#define LCP_OPT_ASYNC_MAP 2 /* async control character map */
142#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */ 142#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */
143#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */ 143#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */
144#define LCP_OPT_MAGIC 5 /* magic number */ 144#define LCP_OPT_MAGIC 5 /* magic number */
145#define LCP_OPT_RESERVED 6 /* reserved */ 145#define LCP_OPT_RESERVED 6 /* reserved */
146#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ 146#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */
147#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ 147#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */
148 148
149#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */ 149#define IPCP_OPT_ADDRESSES 1 /* both IP addresses; deprecated */
150#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol */ 150#define IPCP_OPT_COMPRESSION 2 /* IP compression protocol */
151#define IPCP_OPT_ADDRESS 3 /* local IP address */ 151#define IPCP_OPT_ADDRESS 3 /* local IP address */
152#define IPCP_OPT_PRIMDNS 129 /* primary remote dns address */ 152#define IPCP_OPT_PRIMDNS 129 /* primary remote dns address */
153#define IPCP_OPT_SECDNS 131 /* secondary remote dns address */ 153#define IPCP_OPT_SECDNS 131 /* secondary remote dns address */
154 154
155#define IPCP_UPDATE_LIMIT 8 /* limit of pending IP updating job */ 155#define IPCP_UPDATE_LIMIT 8 /* limit of pending IP updating job */
156#define IPCP_SET_ADDRS 1 /* marker for IP address setting job */ 156#define IPCP_SET_ADDRS 1 /* marker for IP address setting job */
157#define IPCP_CLEAR_ADDRS 2 /* marker for IP address clearing job */ 157#define IPCP_CLEAR_ADDRS 2 /* marker for IP address clearing job */
158 158
159#define IPV6CP_OPT_IFID 1 /* interface identifier */ 159#define IPV6CP_OPT_IFID 1 /* interface identifier */
160#define IPV6CP_OPT_COMPRESSION 2 /* IPv6 compression protocol */ 160#define IPV6CP_OPT_COMPRESSION 2 /* IPv6 compression protocol */
161 161
162#define PAP_REQ 1 /* PAP name/password request */ 162#define PAP_REQ 1 /* PAP name/password request */
163#define PAP_ACK 2 /* PAP acknowledge */ 163#define PAP_ACK 2 /* PAP acknowledge */
164#define PAP_NAK 3 /* PAP fail */ 164#define PAP_NAK 3 /* PAP fail */
165 165
166#define CHAP_CHALLENGE 1 /* CHAP challenge request */ 166#define CHAP_CHALLENGE 1 /* CHAP challenge request */
167#define CHAP_RESPONSE 2 /* CHAP challenge response */ 167#define CHAP_RESPONSE 2 /* CHAP challenge response */
168#define CHAP_SUCCESS 3 /* CHAP response ok */ 168#define CHAP_SUCCESS 3 /* CHAP response ok */
169#define CHAP_FAILURE 4 /* CHAP response failed */ 169#define CHAP_FAILURE 4 /* CHAP response failed */
170 170
171#define CHAP_MD5 5 /* hash algorithm - MD5 */ 171#define CHAP_MD5 5 /* hash algorithm - MD5 */
172 172
173#define CISCO_MULTICAST 0x8f /* Cisco multicast address */ 173#define CISCO_MULTICAST 0x8f /* Cisco multicast address */
174#define CISCO_UNICAST 0x0f /* Cisco unicast address */ 174#define CISCO_UNICAST 0x0f /* Cisco unicast address */
175#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ 175#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */
176#define CISCO_ADDR_REQ 0 /* Cisco address request */ 176#define CISCO_ADDR_REQ 0 /* Cisco address request */
177#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ 177#define CISCO_ADDR_REPLY 1 /* Cisco address reply */
178#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 178#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */
179 179
180/* states are named and numbered according to RFC 1661 */ 180/* states are named and numbered according to RFC 1661 */
181#define STATE_INITIAL 0 181#define STATE_INITIAL 0
182#define STATE_STARTING 1 182#define STATE_STARTING 1
183#define STATE_CLOSED 2 183#define STATE_CLOSED 2
184#define STATE_STOPPED 3 184#define STATE_STOPPED 3
185#define STATE_CLOSING 4 185#define STATE_CLOSING 4
186#define STATE_STOPPING 5 186#define STATE_STOPPING 5
187#define STATE_REQ_SENT 6 187#define STATE_REQ_SENT 6
188#define STATE_ACK_RCVD 7 188#define STATE_ACK_RCVD 7
189#define STATE_ACK_SENT 8 189#define STATE_ACK_SENT 8
190#define STATE_OPENED 9 190#define STATE_OPENED 9
191 191
192struct ppp_header { 192struct ppp_header {
193 uint8_t address; 193 uint8_t address;
194 uint8_t control; 194 uint8_t control;
195 uint16_t protocol; 195 uint16_t protocol;
196} __packed; 196} __packed;
197#define PPP_HEADER_LEN sizeof (struct ppp_header) 197#define PPP_HEADER_LEN sizeof (struct ppp_header)
198 198
199struct lcp_header { 199struct lcp_header {
200 uint8_t type; 200 uint8_t type;
201 uint8_t ident; 201 uint8_t ident;
202 uint16_t len; 202 uint16_t len;
203} __packed; 203} __packed;
204#define LCP_HEADER_LEN sizeof (struct lcp_header) 204#define LCP_HEADER_LEN sizeof (struct lcp_header)
205 205
206struct cisco_packet { 206struct cisco_packet {
207 uint32_t type; 207 uint32_t type;
208 uint32_t par1; 208 uint32_t par1;
209 uint32_t par2; 209 uint32_t par2;
210 uint16_t rel; 210 uint16_t rel;
211 uint16_t time0; 211 uint16_t time0;
212 uint16_t time1; 212 uint16_t time1;
213} __packed; 213} __packed;
214#define CISCO_PACKET_LEN 18 214#define CISCO_PACKET_LEN 18
215 215
216/* 216/*
217 * We follow the spelling and capitalization of RFC 1661 here, to make 217 * We follow the spelling and capitalization of RFC 1661 here, to make
218 * it easier comparing with the standard. Please refer to this RFC in 218 * it easier comparing with the standard. Please refer to this RFC in
219 * case you can't make sense out of these abbreviation; it will also 219 * case you can't make sense out of these abbreviation; it will also
220 * explain the semantics related to the various events and actions. 220 * explain the semantics related to the various events and actions.
221 */ 221 */
222struct cp { 222struct cp {
223 u_short proto; /* PPP control protocol number */ 223 u_short proto; /* PPP control protocol number */
224 u_char protoidx; /* index into state table in struct sppp */ 224 u_char protoidx; /* index into state table in struct sppp */
225 u_char flags; 225 u_char flags;
226#define CP_LCP 0x01 /* this is the LCP */ 226#define CP_LCP 0x01 /* this is the LCP */
227#define CP_AUTH 0x02 /* this is an authentication protocol */ 227#define CP_AUTH 0x02 /* this is an authentication protocol */
228#define CP_NCP 0x04 /* this is a NCP */ 228#define CP_NCP 0x04 /* this is a NCP */
229#define CP_QUAL 0x08 /* this is a quality reporting protocol */ 229#define CP_QUAL 0x08 /* this is a quality reporting protocol */
230 const char *name; /* name of this control protocol */ 230 const char *name; /* name of this control protocol */
231 /* event handlers */ 231 /* event handlers */
232 void (*Up)(struct sppp *sp); 232 void (*Up)(struct sppp *sp);
233 void (*Down)(struct sppp *sp); 233 void (*Down)(struct sppp *sp);
234 void (*Open)(struct sppp *sp); 234 void (*Open)(struct sppp *sp);
235 void (*Close)(struct sppp *sp); 235 void (*Close)(struct sppp *sp);
236 void (*TO)(void *sp); 236 void (*TO)(void *sp);
237 int (*RCR)(struct sppp *sp, struct lcp_header *h, int len); 237 int (*RCR)(struct sppp *sp, struct lcp_header *h, int len);
238 void (*RCN_rej)(struct sppp *sp, struct lcp_header *h, int len); 238 void (*RCN_rej)(struct sppp *sp, struct lcp_header *h, int len);
239 void (*RCN_nak)(struct sppp *sp, struct lcp_header *h, int len); 239 void (*RCN_nak)(struct sppp *sp, struct lcp_header *h, int len);
240 /* actions */ 240 /* actions */
241 void (*tlu)(struct sppp *sp); 241 void (*tlu)(struct sppp *sp);
242 void (*tld)(struct sppp *sp); 242 void (*tld)(struct sppp *sp);
243 void (*tls)(struct sppp *sp); 243 void (*tls)(struct sppp *sp);
244 void (*tlf)(struct sppp *sp); 244 void (*tlf)(struct sppp *sp);
245 void (*scr)(struct sppp *sp); 245 void (*scr)(struct sppp *sp);
246}; 246};
247 247
248static struct sppp *spppq; 248static struct sppp *spppq;
249static kmutex_t *spppq_lock = NULL; 249static kmutex_t *spppq_lock = NULL;
250static callout_t keepalive_ch; 250static callout_t keepalive_ch;
251 251
252#define SPPPQ_LOCK() if (spppq_lock) \ 252#define SPPPQ_LOCK() if (spppq_lock) \
253 mutex_enter(spppq_lock); 253 mutex_enter(spppq_lock);
254#define SPPPQ_UNLOCK() if (spppq_lock) \ 254#define SPPPQ_UNLOCK() if (spppq_lock) \
255 mutex_exit(spppq_lock); 255 mutex_exit(spppq_lock);
256 256
257#define SPPP_LOCK(_sp, _op) rw_enter(&(_sp)->pp_lock, (_op)) 257#define SPPP_LOCK(_sp, _op) rw_enter(&(_sp)->pp_lock, (_op))
258#define SPPP_UNLOCK(_sp) rw_exit(&(_sp)->pp_lock) 258#define SPPP_UNLOCK(_sp) rw_exit(&(_sp)->pp_lock)
259#define SPPP_WLOCKED(_sp) rw_write_held(&(_sp)->pp_lock) 259#define SPPP_WLOCKED(_sp) rw_write_held(&(_sp)->pp_lock)
260#define SPPP_UPGRADE(_sp) do{ \ 260#define SPPP_UPGRADE(_sp) do{ \
261 SPPP_UNLOCK(_sp); \ 261 SPPP_UNLOCK(_sp); \
262 SPPP_LOCK(_sp, RW_WRITER); \ 262 SPPP_LOCK(_sp, RW_WRITER); \
263}while (0) 263}while (0)
264#define SPPP_DOWNGRADE(_sp) rw_downgrade(&(_sp)->pp_lock) 264#define SPPP_DOWNGRADE(_sp) rw_downgrade(&(_sp)->pp_lock)
265 265
266#ifdef INET 266#ifdef INET
267#ifndef SPPPSUBR_MPSAFE 267#ifndef SPPPSUBR_MPSAFE
268/* 268/*
269 * The following disgusting hack gets around the problem that IP TOS 269 * The following disgusting hack gets around the problem that IP TOS
270 * can't be set yet. We want to put "interactive" traffic on a high 270 * can't be set yet. We want to put "interactive" traffic on a high
271 * priority queue. To decide if traffic is interactive, we check that 271 * priority queue. To decide if traffic is interactive, we check that
272 * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control. 272 * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control.
273 * 273 *
274 * XXX is this really still necessary? - joerg - 274 * XXX is this really still necessary? - joerg -
275 */ 275 */
276static u_short interactive_ports[8] = { 276static u_short interactive_ports[8] = {
277 0, 513, 0, 0, 277 0, 513, 0, 0,
278 0, 21, 0, 23, 278 0, 21, 0, 23,
279}; 279};
280#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p)) 280#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p))
281#endif /* SPPPSUBR_MPSAFE */ 281#endif /* SPPPSUBR_MPSAFE */
282#endif 282#endif
283 283
284/* almost every function needs these */ 284/* almost every function needs these */
285#define STDDCL \ 285#define STDDCL \
286 struct ifnet *ifp = &sp->pp_if; \ 286 struct ifnet *ifp = &sp->pp_if; \
287 int debug = ifp->if_flags & IFF_DEBUG 287 int debug = ifp->if_flags & IFF_DEBUG
288 288
289static int sppp_output(struct ifnet *ifp, struct mbuf *m, 289static int sppp_output(struct ifnet *ifp, struct mbuf *m,
290 const struct sockaddr *dst, const struct rtentry *rt); 290 const struct sockaddr *dst, const struct rtentry *rt);
291 291
292static void sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2); 292static void sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2);
293static void sppp_cisco_input(struct sppp *sp, struct mbuf *m); 293static void sppp_cisco_input(struct sppp *sp, struct mbuf *m);
294 294
295static void sppp_cp_input(const struct cp *cp, struct sppp *sp, 295static void sppp_cp_input(const struct cp *cp, struct sppp *sp,
296 struct mbuf *m); 296 struct mbuf *m);
297static void sppp_cp_send(struct sppp *sp, u_short proto, u_char type, 297static void sppp_cp_send(struct sppp *sp, u_short proto, u_char type,
298 u_char ident, u_short len, void *data); 298 u_char ident, u_short len, void *data);
299/* static void sppp_cp_timeout(void *arg); */ 299/* static void sppp_cp_timeout(void *arg); */
300static void sppp_cp_change_state(const struct cp *cp, struct sppp *sp, 300static void sppp_cp_change_state(const struct cp *cp, struct sppp *sp,
301 int newstate); 301 int newstate);
302static void sppp_auth_send(const struct cp *cp, 302static void sppp_auth_send(const struct cp *cp,
303 struct sppp *sp, unsigned int type, unsigned int id, 303 struct sppp *sp, unsigned int type, unsigned int id,
304 ...); 304 ...);
305 305
306static void sppp_up_event(const struct cp *cp, struct sppp *sp); 306static void sppp_up_event(const struct cp *cp, struct sppp *sp);
307static void sppp_down_event(const struct cp *cp, struct sppp *sp); 307static void sppp_down_event(const struct cp *cp, struct sppp *sp);
308static void sppp_open_event(const struct cp *cp, struct sppp *sp); 308static void sppp_open_event(const struct cp *cp, struct sppp *sp);
309static void sppp_close_event(const struct cp *cp, struct sppp *sp); 309static void sppp_close_event(const struct cp *cp, struct sppp *sp);
310static void sppp_to_event(const struct cp *cp, struct sppp *sp); 310static void sppp_to_event(const struct cp *cp, struct sppp *sp);
311 311
312static void sppp_null(struct sppp *sp); 312static void sppp_null(struct sppp *sp);
313 313
314static void sppp_lcp_init(struct sppp *sp); 314static void sppp_lcp_init(struct sppp *sp);
315static void sppp_lcp_up(struct sppp *sp); 315static void sppp_lcp_up(struct sppp *sp);
316static void sppp_lcp_down(struct sppp *sp); 316static void sppp_lcp_down(struct sppp *sp);
317static void sppp_lcp_open(struct sppp *sp); 317static void sppp_lcp_open(struct sppp *sp);
318static void sppp_lcp_close(struct sppp *sp); 318static void sppp_lcp_close(struct sppp *sp);
319static void sppp_lcp_TO(void *sp); 319static void sppp_lcp_TO(void *sp);
320static int sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len); 320static int sppp_lcp_RCR(struct sppp *sp, struct lcp_header *h, int len);
321static void sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); 321static void sppp_lcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
322static void sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); 322static void sppp_lcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
323static void sppp_lcp_tlu(struct sppp *sp); 323static void sppp_lcp_tlu(struct sppp *sp);
324static void sppp_lcp_tld(struct sppp *sp); 324static void sppp_lcp_tld(struct sppp *sp);
325static void sppp_lcp_tls(struct sppp *sp); 325static void sppp_lcp_tls(struct sppp *sp);
326static void sppp_lcp_tlf(struct sppp *sp); 326static void sppp_lcp_tlf(struct sppp *sp);
327static void sppp_lcp_scr(struct sppp *sp); 327static void sppp_lcp_scr(struct sppp *sp);
328static void sppp_lcp_check_and_close(struct sppp *sp); 328static void sppp_lcp_check_and_close(struct sppp *sp);
329static int sppp_ncp_check(struct sppp *sp); 329static int sppp_ncp_check(struct sppp *sp);
330 330
331static void sppp_ipcp_init(struct sppp *sp); 331static void sppp_ipcp_init(struct sppp *sp);
332static void sppp_ipcp_up(struct sppp *sp); 332static void sppp_ipcp_up(struct sppp *sp);
333static void sppp_ipcp_down(struct sppp *sp); 333static void sppp_ipcp_down(struct sppp *sp);
334static void sppp_ipcp_open(struct sppp *sp); 334static void sppp_ipcp_open(struct sppp *sp);
335static void sppp_ipcp_close(struct sppp *sp); 335static void sppp_ipcp_close(struct sppp *sp);
336static void sppp_ipcp_TO(void *sp); 336static void sppp_ipcp_TO(void *sp);
337static int sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len); 337static int sppp_ipcp_RCR(struct sppp *sp, struct lcp_header *h, int len);
338static void sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); 338static void sppp_ipcp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
339static void sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); 339static void sppp_ipcp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
340static void sppp_ipcp_tlu(struct sppp *sp); 340static void sppp_ipcp_tlu(struct sppp *sp);
341static void sppp_ipcp_tld(struct sppp *sp); 341static void sppp_ipcp_tld(struct sppp *sp);
342static void sppp_ipcp_tls(struct sppp *sp); 342static void sppp_ipcp_tls(struct sppp *sp);
343static void sppp_ipcp_tlf(struct sppp *sp); 343static void sppp_ipcp_tlf(struct sppp *sp);
344static void sppp_ipcp_scr(struct sppp *sp); 344static void sppp_ipcp_scr(struct sppp *sp);
345 345
346static void sppp_ipv6cp_init(struct sppp *sp); 346static void sppp_ipv6cp_init(struct sppp *sp);
347static void sppp_ipv6cp_up(struct sppp *sp); 347static void sppp_ipv6cp_up(struct sppp *sp);
348static void sppp_ipv6cp_down(struct sppp *sp); 348static void sppp_ipv6cp_down(struct sppp *sp);
349static void sppp_ipv6cp_open(struct sppp *sp); 349static void sppp_ipv6cp_open(struct sppp *sp);
350static void sppp_ipv6cp_close(struct sppp *sp); 350static void sppp_ipv6cp_close(struct sppp *sp);
351static void sppp_ipv6cp_TO(void *sp); 351static void sppp_ipv6cp_TO(void *sp);
352static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len); 352static int sppp_ipv6cp_RCR(struct sppp *sp, struct lcp_header *h, int len);
353static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len); 353static void sppp_ipv6cp_RCN_rej(struct sppp *sp, struct lcp_header *h, int len);
354static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len); 354static void sppp_ipv6cp_RCN_nak(struct sppp *sp, struct lcp_header *h, int len);
355static void sppp_ipv6cp_tlu(struct sppp *sp); 355static void sppp_ipv6cp_tlu(struct sppp *sp);
356static void sppp_ipv6cp_tld(struct sppp *sp); 356static void sppp_ipv6cp_tld(struct sppp *sp);
357static void sppp_ipv6cp_tls(struct sppp *sp); 357static void sppp_ipv6cp_tls(struct sppp *sp);
358static void sppp_ipv6cp_tlf(struct sppp *sp); 358static void sppp_ipv6cp_tlf(struct sppp *sp);
359static void sppp_ipv6cp_scr(struct sppp *sp); 359static void sppp_ipv6cp_scr(struct sppp *sp);
360 360
361static void sppp_pap_input(struct sppp *sp, struct mbuf *m); 361static void sppp_pap_input(struct sppp *sp, struct mbuf *m);
362static void sppp_pap_init(struct sppp *sp); 362static void sppp_pap_init(struct sppp *sp);
363static void sppp_pap_open(struct sppp *sp); 363static void sppp_pap_open(struct sppp *sp);
364static void sppp_pap_close(struct sppp *sp); 364static void sppp_pap_close(struct sppp *sp);
365static void sppp_pap_TO(void *sp); 365static void sppp_pap_TO(void *sp);
366static void sppp_pap_my_TO(void *sp); 366static void sppp_pap_my_TO(void *sp);
367static void sppp_pap_tlu(struct sppp *sp); 367static void sppp_pap_tlu(struct sppp *sp);
368static void sppp_pap_tld(struct sppp *sp); 368static void sppp_pap_tld(struct sppp *sp);
369static void sppp_pap_scr(struct sppp *sp); 369static void sppp_pap_scr(struct sppp *sp);
370 370
371static void sppp_chap_input(struct sppp *sp, struct mbuf *m); 371static void sppp_chap_input(struct sppp *sp, struct mbuf *m);
372static void sppp_chap_init(struct sppp *sp); 372static void sppp_chap_init(struct sppp *sp);
373static void sppp_chap_open(struct sppp *sp); 373static void sppp_chap_open(struct sppp *sp);
374static void sppp_chap_close(struct sppp *sp); 374static void sppp_chap_close(struct sppp *sp);
375static void sppp_chap_TO(void *sp); 375static void sppp_chap_TO(void *sp);
376static void sppp_chap_tlu(struct sppp *sp); 376static void sppp_chap_tlu(struct sppp *sp);
377static void sppp_chap_tld(struct sppp *sp); 377static void sppp_chap_tld(struct sppp *sp);
378static void sppp_chap_scr(struct sppp *sp); 378static void sppp_chap_scr(struct sppp *sp);
379 379
380static const char *sppp_auth_type_name(u_short proto, u_char type); 380static const char *sppp_auth_type_name(u_short proto, u_char type);
381static const char *sppp_cp_type_name(u_char type); 381static const char *sppp_cp_type_name(u_char type);
382static const char *sppp_dotted_quad(uint32_t addr); 382static const char *sppp_dotted_quad(uint32_t addr);
383static const char *sppp_ipcp_opt_name(u_char opt); 383static const char *sppp_ipcp_opt_name(u_char opt);
384#ifdef INET6 384#ifdef INET6
385static const char *sppp_ipv6cp_opt_name(u_char opt); 385static const char *sppp_ipv6cp_opt_name(u_char opt);
386#endif 386#endif
387static const char *sppp_lcp_opt_name(u_char opt); 387static const char *sppp_lcp_opt_name(u_char opt);
388static const char *sppp_phase_name(int phase); 388static const char *sppp_phase_name(int phase);
389static const char *sppp_proto_name(u_short proto); 389static const char *sppp_proto_name(u_short proto);
390static const char *sppp_state_name(int state); 390static const char *sppp_state_name(int state);
391static int sppp_params(struct sppp *sp, u_long cmd, void *data); 391static int sppp_params(struct sppp *sp, u_long cmd, void *data);
392#ifdef INET 392#ifdef INET
393static void sppp_get_ip_addrs(struct sppp *sp, uint32_t *src, uint32_t *dst, 393static void sppp_get_ip_addrs(struct sppp *sp, uint32_t *src, uint32_t *dst,
394 uint32_t *srcmask); 394 uint32_t *srcmask);
395static void sppp_set_ip_addrs_work(struct work *wk, struct sppp *sp); 395static void sppp_set_ip_addrs_work(struct work *wk, struct sppp *sp);
396static void sppp_set_ip_addrs(struct sppp *sp); 396static void sppp_set_ip_addrs(struct sppp *sp);
397static void sppp_clear_ip_addrs_work(struct work *wk, struct sppp *sp); 397static void sppp_clear_ip_addrs_work(struct work *wk, struct sppp *sp);
398static void sppp_clear_ip_addrs(struct sppp *sp); 398static void sppp_clear_ip_addrs(struct sppp *sp);
399static void sppp_update_ip_addrs_work(struct work *wk, void *arg); 399static void sppp_update_ip_addrs_work(struct work *wk, void *arg);
400#endif 400#endif
401static void sppp_keepalive(void *dummy); 401static void sppp_keepalive(void *dummy);
402static void sppp_phase_network(struct sppp *sp); 402static void sppp_phase_network(struct sppp *sp);
403static void sppp_print_bytes(const u_char *p, u_short len); 403static void sppp_print_bytes(const u_char *p, u_short len);
404static void sppp_print_string(const char *p, u_short len); 404static void sppp_print_string(const char *p, u_short len);
405#ifdef INET6 405#ifdef INET6
406static void sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src, 406static void sppp_get_ip6_addrs(struct sppp *sp, struct in6_addr *src,
407 struct in6_addr *dst, struct in6_addr *srcmask); 407 struct in6_addr *dst, struct in6_addr *srcmask);
408#ifdef IPV6CP_MYIFID_DYN 408#ifdef IPV6CP_MYIFID_DYN
409static void sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src); 409static void sppp_set_ip6_addr(struct sppp *sp, const struct in6_addr *src);
410static void sppp_gen_ip6_addr(struct sppp *sp, const struct in6_addr *src); 410static void sppp_gen_ip6_addr(struct sppp *sp, const struct in6_addr *src);
411#endif 411#endif
412static void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *src); 412static void sppp_suggest_ip6_addr(struct sppp *sp, struct in6_addr *src);
413#endif 413#endif
414 414
415static void sppp_notify_up(struct sppp *); 415static void sppp_notify_up(struct sppp *);
416static void sppp_notify_down(struct sppp *); 416static void sppp_notify_down(struct sppp *);
417static void sppp_notify_tls_wlocked(struct sppp *); 417static void sppp_notify_tls_wlocked(struct sppp *);
418static void sppp_notify_tlf_wlocked(struct sppp *); 418static void sppp_notify_tlf_wlocked(struct sppp *);
419#ifdef INET6 419#ifdef INET6
420static void sppp_notify_con_wlocked(struct sppp *); 420static void sppp_notify_con_wlocked(struct sppp *);
421#endif 421#endif
422static void sppp_notify_con(struct sppp *); 422static void sppp_notify_con(struct sppp *);
423 423
424static void sppp_notify_chg_wlocked(struct sppp *); 424static void sppp_notify_chg_wlocked(struct sppp *);
425 425
426 426
427/* our control protocol descriptors */ 427/* our control protocol descriptors */
428static const struct cp lcp = { 428static const struct cp lcp = {
429 PPP_LCP, IDX_LCP, CP_LCP, "lcp", 429 PPP_LCP, IDX_LCP, CP_LCP, "lcp",
430 sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close, 430 sppp_lcp_up, sppp_lcp_down, sppp_lcp_open, sppp_lcp_close,
431 sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak, 431 sppp_lcp_TO, sppp_lcp_RCR, sppp_lcp_RCN_rej, sppp_lcp_RCN_nak,
432 sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf, 432 sppp_lcp_tlu, sppp_lcp_tld, sppp_lcp_tls, sppp_lcp_tlf,
433 sppp_lcp_scr 433 sppp_lcp_scr
434}; 434};
435 435
436static const struct cp ipcp = { 436static const struct cp ipcp = {
437 PPP_IPCP, IDX_IPCP, 437 PPP_IPCP, IDX_IPCP,
438#ifdef INET 438#ifdef INET
439 CP_NCP, /*don't run IPCP if there's no IPv4 support*/ 439 CP_NCP, /*don't run IPCP if there's no IPv4 support*/
440#else 440#else
441 0, 441 0,
442#endif 442#endif
443 "ipcp", 443 "ipcp",
444 sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close, 444 sppp_ipcp_up, sppp_ipcp_down, sppp_ipcp_open, sppp_ipcp_close,
445 sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak, 445 sppp_ipcp_TO, sppp_ipcp_RCR, sppp_ipcp_RCN_rej, sppp_ipcp_RCN_nak,
446 sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf, 446 sppp_ipcp_tlu, sppp_ipcp_tld, sppp_ipcp_tls, sppp_ipcp_tlf,
447 sppp_ipcp_scr 447 sppp_ipcp_scr
448}; 448};
449 449
450static const struct cp ipv6cp = { 450static const struct cp ipv6cp = {
451 PPP_IPV6CP, IDX_IPV6CP, 451 PPP_IPV6CP, IDX_IPV6CP,
452#ifdef INET6 /*don't run IPv6CP if there's no IPv6 support*/ 452#ifdef INET6 /*don't run IPv6CP if there's no IPv6 support*/
453 CP_NCP, 453 CP_NCP,
454#else 454#else
455 0, 455 0,
456#endif 456#endif
457 "ipv6cp", 457 "ipv6cp",
458 sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close, 458 sppp_ipv6cp_up, sppp_ipv6cp_down, sppp_ipv6cp_open, sppp_ipv6cp_close,
459 sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak, 459 sppp_ipv6cp_TO, sppp_ipv6cp_RCR, sppp_ipv6cp_RCN_rej, sppp_ipv6cp_RCN_nak,
460 sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf, 460 sppp_ipv6cp_tlu, sppp_ipv6cp_tld, sppp_ipv6cp_tls, sppp_ipv6cp_tlf,
461 sppp_ipv6cp_scr 461 sppp_ipv6cp_scr
462}; 462};
463 463
464static const struct cp pap = { 464static const struct cp pap = {
465 PPP_PAP, IDX_PAP, CP_AUTH, "pap", 465 PPP_PAP, IDX_PAP, CP_AUTH, "pap",
466 sppp_null, sppp_null, sppp_pap_open, sppp_pap_close, 466 sppp_null, sppp_null, sppp_pap_open, sppp_pap_close,
467 sppp_pap_TO, 0, 0, 0, 467 sppp_pap_TO, 0, 0, 0,
468 sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null, 468 sppp_pap_tlu, sppp_pap_tld, sppp_null, sppp_null,
469 sppp_pap_scr 469 sppp_pap_scr
470}; 470};
471 471
472static const struct cp chap = { 472static const struct cp chap = {
473 PPP_CHAP, IDX_CHAP, CP_AUTH, "chap", 473 PPP_CHAP, IDX_CHAP, CP_AUTH, "chap",
474 sppp_null, sppp_null, sppp_chap_open, sppp_chap_close, 474 sppp_null, sppp_null, sppp_chap_open, sppp_chap_close,
475 sppp_chap_TO, 0, 0, 0, 475 sppp_chap_TO, 0, 0, 0,
476 sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null, 476 sppp_chap_tlu, sppp_chap_tld, sppp_null, sppp_null,
477 sppp_chap_scr 477 sppp_chap_scr
478}; 478};
479 479
480static const struct cp *cps[IDX_COUNT] = { 480static const struct cp *cps[IDX_COUNT] = {
481 &lcp, /* IDX_LCP */ 481 &lcp, /* IDX_LCP */
482 &ipcp, /* IDX_IPCP */ 482 &ipcp, /* IDX_IPCP */
483 &ipv6cp, /* IDX_IPV6CP */ 483 &ipv6cp, /* IDX_IPV6CP */
484 &pap, /* IDX_PAP */ 484 &pap, /* IDX_PAP */
485 &chap, /* IDX_CHAP */ 485 &chap, /* IDX_CHAP */
486}; 486};
487 487
488static void 488static void
489sppp_change_phase(struct sppp *sp, int phase) 489sppp_change_phase(struct sppp *sp, int phase)
490{ 490{
491 STDDCL; 491 STDDCL;
492 492
493 KASSERT(SPPP_WLOCKED(sp)); 493 KASSERT(SPPP_WLOCKED(sp));
494 494
495 if (sp->pp_phase == phase) 495 if (sp->pp_phase == phase)
496 return; 496 return;
497 497
498 sp->pp_phase = phase; 498 sp->pp_phase = phase;
499 499
500 if (phase == SPPP_PHASE_NETWORK) 500 if (phase == SPPP_PHASE_NETWORK)
501 if_link_state_change(ifp, LINK_STATE_UP); 501 if_link_state_change(ifp, LINK_STATE_UP);
502 else 502 else
503 if_link_state_change(ifp, LINK_STATE_DOWN); 503 if_link_state_change(ifp, LINK_STATE_DOWN);
504 504
505 if (debug) 505 if (debug)
506 { 506 {
507 log(LOG_INFO, "%s: phase %s\n", ifp->if_xname, 507 log(LOG_INFO, "%s: phase %s\n", ifp->if_xname,
508 sppp_phase_name(sp->pp_phase)); 508 sppp_phase_name(sp->pp_phase));
509 } 509 }
510} 510}
511 511
512/* 512/*
513 * Exported functions, comprising our interface to the lower layer. 513 * Exported functions, comprising our interface to the lower layer.
514 */ 514 */
515 515
516/* 516/*
517 * Process the received packet. 517 * Process the received packet.
518 */ 518 */
519void 519void
520sppp_input(struct ifnet *ifp, struct mbuf *m) 520sppp_input(struct ifnet *ifp, struct mbuf *m)
521{ 521{
522 struct ppp_header *h = NULL; 522 struct ppp_header *h = NULL;
523 pktqueue_t *pktq = NULL; 523 pktqueue_t *pktq = NULL;
524 struct ifqueue *inq = NULL; 524 struct ifqueue *inq = NULL;
525 uint16_t protocol; 525 uint16_t protocol;
526 struct sppp *sp = (struct sppp *)ifp; 526 struct sppp *sp = (struct sppp *)ifp;
527 int debug = ifp->if_flags & IFF_DEBUG; 527 int debug = ifp->if_flags & IFF_DEBUG;
528 int isr = 0; 528 int isr = 0;
529 529
530 SPPP_LOCK(sp, RW_READER); 530 SPPP_LOCK(sp, RW_READER);
531 531
532 if (ifp->if_flags & IFF_UP) { 532 if (ifp->if_flags & IFF_UP) {
533 /* Count received bytes, add hardware framing */ 533 /* Count received bytes, add hardware framing */
534 ifp->if_ibytes += m->m_pkthdr.len + sp->pp_framebytes; 534 ifp->if_ibytes += m->m_pkthdr.len + sp->pp_framebytes;
535 /* Note time of last receive */ 535 /* Note time of last receive */
536 sp->pp_last_receive = time_uptime; 536 sp->pp_last_receive = time_uptime;
537 } 537 }
538 538
539 if (m->m_pkthdr.len <= PPP_HEADER_LEN) { 539 if (m->m_pkthdr.len <= PPP_HEADER_LEN) {
540 /* Too small packet, drop it. */ 540 /* Too small packet, drop it. */
541 if (debug) 541 if (debug)
542 log(LOG_DEBUG, 542 log(LOG_DEBUG,
543 "%s: input packet is too small, %d bytes\n", 543 "%s: input packet is too small, %d bytes\n",
544 ifp->if_xname, m->m_pkthdr.len); 544 ifp->if_xname, m->m_pkthdr.len);
545 drop: 545 drop:
546 ++ifp->if_ierrors; 546 ++ifp->if_ierrors;
547 ++ifp->if_iqdrops; 547 ++ifp->if_iqdrops;
548 m_freem(m); 548 m_freem(m);
549 SPPP_UNLOCK(sp); 549 SPPP_UNLOCK(sp);
550 return; 550 return;
551 } 551 }
552 552
553 if (sp->pp_flags & PP_NOFRAMING) { 553 if (sp->pp_flags & PP_NOFRAMING) {
554 memcpy(&protocol, mtod(m, void *), 2); 554 memcpy(&protocol, mtod(m, void *), 2);
555 protocol = ntohs(protocol); 555 protocol = ntohs(protocol);
556 m_adj(m, 2); 556 m_adj(m, 2);
557 } else { 557 } else {
558 558
559 /* Get PPP header. */ 559 /* Get PPP header. */
560 h = mtod(m, struct ppp_header *); 560 h = mtod(m, struct ppp_header *);
561 m_adj(m, PPP_HEADER_LEN); 561 m_adj(m, PPP_HEADER_LEN);
562 562
563 switch (h->address) { 563 switch (h->address) {
564 case PPP_ALLSTATIONS: 564 case PPP_ALLSTATIONS:
565 if (h->control != PPP_UI) 565 if (h->control != PPP_UI)
566 goto invalid; 566 goto invalid;
567 if (sp->pp_flags & PP_CISCO) { 567 if (sp->pp_flags & PP_CISCO) {
568 if (debug) 568 if (debug)
569 log(LOG_DEBUG, 569 log(LOG_DEBUG,
570 "%s: PPP packet in Cisco mode " 570 "%s: PPP packet in Cisco mode "
571 "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 571 "<addr=0x%x ctrl=0x%x proto=0x%x>\n",
572 ifp->if_xname, 572 ifp->if_xname,
573 h->address, h->control, ntohs(h->protocol)); 573 h->address, h->control, ntohs(h->protocol));
574 goto drop; 574 goto drop;
575 } 575 }
576 break; 576 break;
577 case CISCO_MULTICAST: 577 case CISCO_MULTICAST:
578 case CISCO_UNICAST: 578 case CISCO_UNICAST:
579 /* Don't check the control field here (RFC 1547). */ 579 /* Don't check the control field here (RFC 1547). */
580 if (! (sp->pp_flags & PP_CISCO)) { 580 if (! (sp->pp_flags & PP_CISCO)) {
581 if (debug) 581 if (debug)
582 log(LOG_DEBUG, 582 log(LOG_DEBUG,
583 "%s: Cisco packet in PPP mode " 583 "%s: Cisco packet in PPP mode "
584 "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 584 "<addr=0x%x ctrl=0x%x proto=0x%x>\n",
585 ifp->if_xname, 585 ifp->if_xname,
586 h->address, h->control, ntohs(h->protocol)); 586 h->address, h->control, ntohs(h->protocol));
587 goto drop; 587 goto drop;
588 } 588 }
589 switch (ntohs(h->protocol)) { 589 switch (ntohs(h->protocol)) {
590 default: 590 default:
591 ++ifp->if_noproto; 591 ++ifp->if_noproto;
592 goto invalid; 592 goto invalid;
593 case CISCO_KEEPALIVE: 593 case CISCO_KEEPALIVE:
594 SPPP_UNLOCK(sp); 594 SPPP_UNLOCK(sp);
595 sppp_cisco_input((struct sppp *) ifp, m); 595 sppp_cisco_input((struct sppp *) ifp, m);
596 m_freem(m); 596 m_freem(m);
597 return; 597 return;
598#ifdef INET 598#ifdef INET
599 case ETHERTYPE_IP: 599 case ETHERTYPE_IP:
600 pktq = ip_pktq; 600 pktq = ip_pktq;
601 break; 601 break;
602#endif 602#endif
603#ifdef INET6 603#ifdef INET6
604 case ETHERTYPE_IPV6: 604 case ETHERTYPE_IPV6:
605 pktq = ip6_pktq; 605 pktq = ip6_pktq;
606 break; 606 break;
607#endif 607#endif
608 } 608 }
609 goto queue_pkt; 609 goto queue_pkt;
610 default: /* Invalid PPP packet. */ 610 default: /* Invalid PPP packet. */
611 invalid: 611 invalid:
612 if (debug) 612 if (debug)
613 log(LOG_DEBUG, 613 log(LOG_DEBUG,
614 "%s: invalid input packet " 614 "%s: invalid input packet "
615 "<addr=0x%x ctrl=0x%x proto=0x%x>\n", 615 "<addr=0x%x ctrl=0x%x proto=0x%x>\n",
616 ifp->if_xname, 616 ifp->if_xname,
617 h->address, h->control, ntohs(h->protocol)); 617 h->address, h->control, ntohs(h->protocol));
618 goto drop; 618 goto drop;
619 } 619 }
620 protocol = ntohs(h->protocol); 620 protocol = ntohs(h->protocol);
621 } 621 }
622 622
623 switch (protocol) { 623 switch (protocol) {
624 default: 624 default:
625 if (sp->state[IDX_LCP] == STATE_OPENED) { 625 if (sp->state[IDX_LCP] == STATE_OPENED) {
626 uint16_t prot = htons(protocol); 626 uint16_t prot = htons(protocol);
627 627
628 SPPP_UPGRADE(sp); 628 SPPP_UPGRADE(sp);
629 sppp_cp_send(sp, PPP_LCP, PROTO_REJ, 629 sppp_cp_send(sp, PPP_LCP, PROTO_REJ,
630 ++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2, 630 ++sp->pp_seq[IDX_LCP], m->m_pkthdr.len + 2,
631 &prot); 631 &prot);
632 SPPP_DOWNGRADE(sp); 632 SPPP_DOWNGRADE(sp);
633 } 633 }
634 if (debug) 634 if (debug)
635 log(LOG_DEBUG, 635 log(LOG_DEBUG,
636 "%s: invalid input protocol " 636 "%s: invalid input protocol "
637 "<proto=0x%x>\n", ifp->if_xname, ntohs(protocol)); 637 "<proto=0x%x>\n", ifp->if_xname, ntohs(protocol));
638 ++ifp->if_noproto; 638 ++ifp->if_noproto;
639 goto drop; 639 goto drop;
640 case PPP_LCP: 640 case PPP_LCP:
641 SPPP_UNLOCK(sp); 641 SPPP_UNLOCK(sp);
642 sppp_cp_input(&lcp, sp, m); 642 sppp_cp_input(&lcp, sp, m);
643 m_freem(m); 643 m_freem(m);
644 return; 644 return;
645 case PPP_PAP: 645 case PPP_PAP:
646 SPPP_UNLOCK(sp); 646 SPPP_UNLOCK(sp);
647 if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) { 647 if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) {
648 sppp_pap_input(sp, m); 648 sppp_pap_input(sp, m);
649 } 649 }
650 m_freem(m); 650 m_freem(m);
651 return; 651 return;
652 case PPP_CHAP: 652 case PPP_CHAP:
653 SPPP_UNLOCK(sp); 653 SPPP_UNLOCK(sp);
654 if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) { 654 if (sp->pp_phase >= SPPP_PHASE_AUTHENTICATE) {
655 sppp_chap_input(sp, m); 655 sppp_chap_input(sp, m);
656 } 656 }
657 m_freem(m); 657 m_freem(m);
658 return; 658 return;
659#ifdef INET 659#ifdef INET
660 case PPP_IPCP: 660 case PPP_IPCP:
661 SPPP_UNLOCK(sp); 661 SPPP_UNLOCK(sp);
662 if (sp->pp_phase == SPPP_PHASE_NETWORK) { 662 if (sp->pp_phase == SPPP_PHASE_NETWORK) {
663 sppp_cp_input(&ipcp, sp, m); 663 sppp_cp_input(&ipcp, sp, m);
664 } 664 }
665 m_freem(m); 665 m_freem(m);
666 return; 666 return;
667 case PPP_IP: 667 case PPP_IP:
668 if (sp->state[IDX_IPCP] == STATE_OPENED) { 668 if (sp->state[IDX_IPCP] == STATE_OPENED) {
669 sp->pp_last_activity = time_uptime; 669 sp->pp_last_activity = time_uptime;
670 pktq = ip_pktq; 670 pktq = ip_pktq;
671 } 671 }
672 break; 672 break;
673#endif 673#endif
674#ifdef INET6 674#ifdef INET6
675 case PPP_IPV6CP: 675 case PPP_IPV6CP:
676 SPPP_UNLOCK(sp); 676 SPPP_UNLOCK(sp);
677 if (sp->pp_phase == SPPP_PHASE_NETWORK) { 677 if (sp->pp_phase == SPPP_PHASE_NETWORK) {
678 sppp_cp_input(&ipv6cp, sp, m); 678 sppp_cp_input(&ipv6cp, sp, m);
679 } 679 }
680 m_freem(m); 680 m_freem(m);
681 return; 681 return;
682 682
683 case PPP_IPV6: 683 case PPP_IPV6:
684 if (sp->state[IDX_IPV6CP] == STATE_OPENED) { 684 if (sp->state[IDX_IPV6CP] == STATE_OPENED) {
685 sp->pp_last_activity = time_uptime; 685 sp->pp_last_activity = time_uptime;
686 pktq = ip6_pktq; 686 pktq = ip6_pktq;
687 } 687 }
688 break; 688 break;
689#endif 689#endif
690 } 690 }
691 691
692queue_pkt: 692queue_pkt:
693 if ((ifp->if_flags & IFF_UP) == 0 || (!inq && !pktq)) { 693 if ((ifp->if_flags & IFF_UP) == 0 || (!inq && !pktq)) {
694 goto drop; 694 goto drop;
695 } 695 }
696 696
697 /* Check queue. */ 697 /* Check queue. */
698 if (__predict_true(pktq)) { 698 if (__predict_true(pktq)) {
699 if (__predict_false(!pktq_enqueue(pktq, m, 0))) { 699 if (__predict_false(!pktq_enqueue(pktq, m, 0))) {
700 goto drop; 700 goto drop;
701 } 701 }
702 SPPP_UNLOCK(sp); 702 SPPP_UNLOCK(sp);
703 return; 703 return;
704 } 704 }
705 705
706 SPPP_UNLOCK(sp); 706 SPPP_UNLOCK(sp);
707 707
708 IFQ_LOCK(inq); 708 IFQ_LOCK(inq);
709 if (IF_QFULL(inq)) { 709 if (IF_QFULL(inq)) {
710 /* Queue overflow. */ 710 /* Queue overflow. */
711 IF_DROP(inq); 711 IF_DROP(inq);
712 IFQ_UNLOCK(inq); 712 IFQ_UNLOCK(inq);
713 if (debug) 713 if (debug)
714 log(LOG_DEBUG, "%s: protocol queue overflow\n", 714 log(LOG_DEBUG, "%s: protocol queue overflow\n",
715 ifp->if_xname); 715 ifp->if_xname);
716 716
717 SPPP_LOCK(sp, RW_READER); 717 SPPP_LOCK(sp, RW_READER);
718 goto drop; 718 goto drop;
719 } 719 }
720 IF_ENQUEUE(inq, m); 720 IF_ENQUEUE(inq, m);
721 IFQ_UNLOCK(inq); 721 IFQ_UNLOCK(inq);
722 schednetisr(isr); 722 schednetisr(isr);
723} 723}
724 724
725/* 725/*
726 * Enqueue transmit packet. 726 * Enqueue transmit packet.
727 */ 727 */
728static int 728static int
729sppp_output(struct ifnet *ifp, struct mbuf *m, 729sppp_output(struct ifnet *ifp, struct mbuf *m,
730 const struct sockaddr *dst, const struct rtentry *rt) 730 const struct sockaddr *dst, const struct rtentry *rt)
731{ 731{
732 struct sppp *sp = (struct sppp *) ifp; 732 struct sppp *sp = (struct sppp *) ifp;
733 struct ppp_header *h = NULL; 733 struct ppp_header *h = NULL;
734#ifndef SPPPSUBR_MPSAFE 734#ifndef SPPPSUBR_MPSAFE
735 struct ifqueue *ifq = NULL; /* XXX */ 735 struct ifqueue *ifq = NULL; /* XXX */
736#endif 736#endif
737 int s, error = 0; 737 int s, error = 0;
738 uint16_t protocol; 738 uint16_t protocol;
739 size_t pktlen; 739 size_t pktlen;
740 740
741 s = splnet(); 741 s = splnet();
742 SPPP_LOCK(sp, RW_READER); 742 SPPP_LOCK(sp, RW_READER);
743 743
744 sp->pp_last_activity = time_uptime; 744 sp->pp_last_activity = time_uptime;
745 745
746 if ((ifp->if_flags & IFF_UP) == 0 || 746 if ((ifp->if_flags & IFF_UP) == 0 ||
747 (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) { 747 (ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == 0) {
748 SPPP_UNLOCK(sp); 748 SPPP_UNLOCK(sp);
749 splx(s); 749 splx(s);
750 750
751 m_freem(m); 751 m_freem(m);
752 752
753 return (ENETDOWN); 753 return (ENETDOWN);
754 } 754 }
755 755
756 if ((ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == IFF_AUTO) { 756 if ((ifp->if_flags & (IFF_RUNNING | IFF_AUTO)) == IFF_AUTO) {
757 /* 757 /*
758 * Interface is not yet running, but auto-dial. Need 758 * Interface is not yet running, but auto-dial. Need
759 * to start LCP for it. 759 * to start LCP for it.
760 */ 760 */
761 ifp->if_flags |= IFF_RUNNING; 761 ifp->if_flags |= IFF_RUNNING;
762 762
763 SPPP_UNLOCK(sp); 763 SPPP_UNLOCK(sp);
764 splx(s); 764 splx(s);
765 765
766 SPPP_LOCK(sp, RW_WRITER); 766 SPPP_LOCK(sp, RW_WRITER);
767 lcp.Open(sp); 767 lcp.Open(sp);
768 SPPP_UNLOCK(sp); 768 SPPP_UNLOCK(sp);
769 769
770 s = splnet(); 770 s = splnet();
771 SPPP_LOCK(sp, RW_READER); 771 SPPP_LOCK(sp, RW_READER);
772 } 772 }
773 773
774 /* 774 /*
775 * If the queueing discipline needs packet classification, 775 * If the queueing discipline needs packet classification,
776 * do it before prepending link headers. 776 * do it before prepending link headers.
777 */ 777 */
778 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 778 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
779 779
780#ifdef INET 780#ifdef INET
781 if (dst->sa_family == AF_INET) { 781 if (dst->sa_family == AF_INET) {
782 struct ip *ip = NULL; 782 struct ip *ip = NULL;
783#ifndef SPPPSUBR_MPSAFE 783#ifndef SPPPSUBR_MPSAFE
784 struct tcphdr *th = NULL; 784 struct tcphdr *th = NULL;
785#endif 785#endif
786 786
787 if (m->m_len >= sizeof(struct ip)) { 787 if (m->m_len >= sizeof(struct ip)) {
788 ip = mtod(m, struct ip *); 788 ip = mtod(m, struct ip *);
789#ifndef SPPPSUBR_MPSAFE 789#ifndef SPPPSUBR_MPSAFE
790 if (ip->ip_p == IPPROTO_TCP && 790 if (ip->ip_p == IPPROTO_TCP &&
791 m->m_len >= sizeof(struct ip) + (ip->ip_hl << 2) + 791 m->m_len >= sizeof(struct ip) + (ip->ip_hl << 2) +
792 sizeof(struct tcphdr)) { 792 sizeof(struct tcphdr)) {
793 th = (struct tcphdr *) 793 th = (struct tcphdr *)
794 ((char *)ip + (ip->ip_hl << 2)); 794 ((char *)ip + (ip->ip_hl << 2));
795 } 795 }
796#endif 796#endif
797 } else 797 } else
798 ip = NULL; 798 ip = NULL;
799 799
800 /* 800 /*
801 * When using dynamic local IP address assignment by using 801 * When using dynamic local IP address assignment by using
802 * 0.0.0.0 as a local address, the first TCP session will 802 * 0.0.0.0 as a local address, the first TCP session will
803 * not connect because the local TCP checksum is computed 803 * not connect because the local TCP checksum is computed
804 * using 0.0.0.0 which will later become our real IP address 804 * using 0.0.0.0 which will later become our real IP address
805 * so the TCP checksum computed at the remote end will 805 * so the TCP checksum computed at the remote end will
806 * become invalid. So we 806 * become invalid. So we
807 * - don't let packets with src ip addr 0 thru 807 * - don't let packets with src ip addr 0 thru
808 * - we flag TCP packets with src ip 0 as an error 808 * - we flag TCP packets with src ip 0 as an error
809 */ 809 */
810 if (ip && ip->ip_src.s_addr == INADDR_ANY) { 810 if (ip && ip->ip_src.s_addr == INADDR_ANY) {
811 uint8_t proto = ip->ip_p; 811 uint8_t proto = ip->ip_p;
812 812
813 SPPP_UNLOCK(sp); 813 SPPP_UNLOCK(sp);
814 splx(s); 814 splx(s);
815 815
816 m_freem(m); 816 m_freem(m);
817 if (proto == IPPROTO_TCP) 817 if (proto == IPPROTO_TCP)
818 return (EADDRNOTAVAIL); 818 return (EADDRNOTAVAIL);
819 else 819 else
820 return (0); 820 return (0);
821 } 821 }
822 822
823#ifndef SPPPSUBR_MPSAFE 823#ifndef SPPPSUBR_MPSAFE
824 /* 824 /*
825 * Put low delay, telnet, rlogin and ftp control packets 825 * Put low delay, telnet, rlogin and ftp control packets
826 * in front of the queue. 826 * in front of the queue.
827 */ 827 */
828 if (!IF_QFULL(&sp->pp_fastq) && 828 if (!IF_QFULL(&sp->pp_fastq) &&
829 ((ip && (ip->ip_tos & IPTOS_LOWDELAY)) || 829 ((ip && (ip->ip_tos & IPTOS_LOWDELAY)) ||
830 (th && (INTERACTIVE(ntohs(th->th_sport)) || 830 (th && (INTERACTIVE(ntohs(th->th_sport)) ||
831 INTERACTIVE(ntohs(th->th_dport)))))) 831 INTERACTIVE(ntohs(th->th_dport))))))
832 ifq = &sp->pp_fastq; 832 ifq = &sp->pp_fastq;
833#endif /* !SPPPSUBR_MPSAFE */ 833#endif /* !SPPPSUBR_MPSAFE */
834 } 834 }
835#endif 835#endif
836 836
837#ifdef INET6 837#ifdef INET6
838 if (dst->sa_family == AF_INET6) { 838 if (dst->sa_family == AF_INET6) {
839 /* XXX do something tricky here? */ 839 /* XXX do something tricky here? */
840 } 840 }
841#endif 841#endif
842 842
843 if ((sp->pp_flags & PP_NOFRAMING) == 0) { 843 if ((sp->pp_flags & PP_NOFRAMING) == 0) {
844 /* 844 /*
845 * Prepend general data packet PPP header. For now, IP only. 845 * Prepend general data packet PPP header. For now, IP only.
846 */ 846 */
847 M_PREPEND(m, PPP_HEADER_LEN, M_DONTWAIT); 847 M_PREPEND(m, PPP_HEADER_LEN, M_DONTWAIT);
848 if (! m) { 848 if (! m) {
849 if (ifp->if_flags & IFF_DEBUG) 849 if (ifp->if_flags & IFF_DEBUG)
850 log(LOG_DEBUG, "%s: no memory for transmit header\n", 850 log(LOG_DEBUG, "%s: no memory for transmit header\n",
851 ifp->if_xname); 851 ifp->if_xname);
852 ++ifp->if_oerrors; 852 ++ifp->if_oerrors;
853 SPPP_UNLOCK(sp); 853 SPPP_UNLOCK(sp);
854 splx(s); 854 splx(s);
855 return (ENOBUFS); 855 return (ENOBUFS);
856 } 856 }
857 /* 857 /*
858 * May want to check size of packet 858 * May want to check size of packet
859 * (albeit due to the implementation it's always enough) 859 * (albeit due to the implementation it's always enough)
860 */ 860 */
861 h = mtod(m, struct ppp_header *); 861 h = mtod(m, struct ppp_header *);
862 if (sp->pp_flags & PP_CISCO) { 862 if (sp->pp_flags & PP_CISCO) {
863 h->address = CISCO_UNICAST; /* unicast address */ 863 h->address = CISCO_UNICAST; /* unicast address */
864 h->control = 0; 864 h->control = 0;
865 } else { 865 } else {
866 h->address = PPP_ALLSTATIONS; /* broadcast address */ 866 h->address = PPP_ALLSTATIONS; /* broadcast address */
867 h->control = PPP_UI; /* Unnumbered Info */ 867 h->control = PPP_UI; /* Unnumbered Info */
868 } 868 }
869 } 869 }
870 870
871 switch (dst->sa_family) { 871 switch (dst->sa_family) {
872#ifdef INET 872#ifdef INET
873 case AF_INET: /* Internet Protocol */ 873 case AF_INET: /* Internet Protocol */
874 if (sp->pp_flags & PP_CISCO) 874 if (sp->pp_flags & PP_CISCO)
875 protocol = htons(ETHERTYPE_IP); 875 protocol = htons(ETHERTYPE_IP);
876 else { 876 else {
877 /* 877 /*
878 * Don't choke with an ENETDOWN early. It's 878 * Don't choke with an ENETDOWN early. It's
879 * possible that we just started dialing out, 879 * possible that we just started dialing out,
880 * so don't drop the packet immediately. If 880 * so don't drop the packet immediately. If
881 * we notice that we run out of buffer space 881 * we notice that we run out of buffer space
882 * below, we will however remember that we are 882 * below, we will however remember that we are
883 * not ready to carry IP packets, and return 883 * not ready to carry IP packets, and return
884 * ENETDOWN, as opposed to ENOBUFS. 884 * ENETDOWN, as opposed to ENOBUFS.
885 */ 885 */
886 protocol = htons(PPP_IP); 886 protocol = htons(PPP_IP);
887 if (sp->state[IDX_IPCP] != STATE_OPENED) 887 if (sp->state[IDX_IPCP] != STATE_OPENED)
888 error = ENETDOWN; 888 error = ENETDOWN;
889 } 889 }
890 break; 890 break;
891#endif 891#endif
892#ifdef INET6 892#ifdef INET6
893 case AF_INET6: /* Internet Protocol version 6 */ 893 case AF_INET6: /* Internet Protocol version 6 */
894 if (sp->pp_flags & PP_CISCO) 894 if (sp->pp_flags & PP_CISCO)
895 protocol = htons(ETHERTYPE_IPV6); 895 protocol = htons(ETHERTYPE_IPV6);
896 else { 896 else {
897 /* 897 /*
898 * Don't choke with an ENETDOWN early. It's 898 * Don't choke with an ENETDOWN early. It's
899 * possible that we just started dialing out, 899 * possible that we just started dialing out,
900 * so don't drop the packet immediately. If 900 * so don't drop the packet immediately. If
901 * we notice that we run out of buffer space 901 * we notice that we run out of buffer space
902 * below, we will however remember that we are 902 * below, we will however remember that we are
903 * not ready to carry IP packets, and return 903 * not ready to carry IP packets, and return
904 * ENETDOWN, as opposed to ENOBUFS. 904 * ENETDOWN, as opposed to ENOBUFS.
905 */ 905 */
906 protocol = htons(PPP_IPV6); 906 protocol = htons(PPP_IPV6);
907 if (sp->state[IDX_IPV6CP] != STATE_OPENED) 907 if (sp->state[IDX_IPV6CP] != STATE_OPENED)
908 error = ENETDOWN; 908 error = ENETDOWN;
909 } 909 }
910 break; 910 break;
911#endif 911#endif
912 default: 912 default:
913 m_freem(m); 913 m_freem(m);
914 ++ifp->if_oerrors; 914 ++ifp->if_oerrors;
915 SPPP_UNLOCK(sp); 915 SPPP_UNLOCK(sp);
916 splx(s); 916 splx(s);
917 return (EAFNOSUPPORT); 917 return (EAFNOSUPPORT);
918 } 918 }
919 919
920 if (sp->pp_flags & PP_NOFRAMING) { 920 if (sp->pp_flags & PP_NOFRAMING) {
921 M_PREPEND(m, 2, M_DONTWAIT); 921 M_PREPEND(m, 2, M_DONTWAIT);
922 if (m == NULL) { 922 if (m == NULL) {
923 if (ifp->if_flags & IFF_DEBUG) 923 if (ifp->if_flags & IFF_DEBUG)
924 log(LOG_DEBUG, "%s: no memory for transmit header\n", 924 log(LOG_DEBUG, "%s: no memory for transmit header\n",
925 ifp->if_xname); 925 ifp->if_xname);
926 ++ifp->if_oerrors; 926 ++ifp->if_oerrors;
927 SPPP_UNLOCK(sp); 927 SPPP_UNLOCK(sp);
928 splx(s); 928 splx(s);
929 return (ENOBUFS); 929 return (ENOBUFS);
930 } 930 }
931 *mtod(m, uint16_t *) = protocol; 931 *mtod(m, uint16_t *) = protocol;
932 } else { 932 } else {
933 h->protocol = protocol; 933 h->protocol = protocol;
934 } 934 }
935 935
936 pktlen = m->m_pkthdr.len; 936 pktlen = m->m_pkthdr.len;
937#ifdef SPPPSUBR_MPSAFE 937#ifdef SPPPSUBR_MPSAFE
938 SPPP_UNLOCK(sp); 938 SPPP_UNLOCK(sp);
939 error = if_transmit_lock(ifp, m); 939 error = if_transmit_lock(ifp, m);
940 SPPP_LOCK(sp, RW_READER); 940 SPPP_LOCK(sp, RW_READER);
941 if (error == 0) 941 if (error == 0)
942 ifp->if_obytes += pktlen + sp->pp_framebytes; 942 ifp->if_obytes += pktlen + sp->pp_framebytes;
943#else /* !SPPPSUBR_MPSAFE */ 943#else /* !SPPPSUBR_MPSAFE */
944 error = ifq_enqueue2(ifp, ifq, m); 944 error = ifq_enqueue2(ifp, ifq, m);
945 945
946 if (error == 0) { 946 if (error == 0) {
947 /* 947 /*
948 * Count output packets and bytes. 948 * Count output packets and bytes.
949 * The packet length includes header + additional hardware 949 * The packet length includes header + additional hardware
950 * framing according to RFC 1333. 950 * framing according to RFC 1333.
951 */ 951 */
952 if (!(ifp->if_flags & IFF_OACTIVE)) { 952 if (!(ifp->if_flags & IFF_OACTIVE)) {
953 SPPP_UNLOCK(sp); 953 SPPP_UNLOCK(sp);
954 if_start_lock(ifp); 954 if_start_lock(ifp);
955 SPPP_LOCK(sp, RW_READER); 955 SPPP_LOCK(sp, RW_READER);
956 } 956 }
957 ifp->if_obytes += pktlen + sp->pp_framebytes; 957 ifp->if_obytes += pktlen + sp->pp_framebytes;
958 } 958 }
959#endif /* !SPPPSUBR_MPSAFE */ 959#endif /* !SPPPSUBR_MPSAFE */
960 SPPP_UNLOCK(sp); 960 SPPP_UNLOCK(sp);
961 splx(s); 961 splx(s);
962 return error; 962 return error;
963} 963}
964 964
965static int 965static int
966sppp_mediachange(struct ifnet *ifp) 966sppp_mediachange(struct ifnet *ifp)
967{ 967{
968 968
969 return (0); 969 return (0);
970} 970}
971 971
972static void 972static void
973sppp_mediastatus(struct ifnet *ifp, struct ifmediareq *imr) 973sppp_mediastatus(struct ifnet *ifp, struct ifmediareq *imr)
974{ 974{
975 struct sppp *sp = (struct sppp *)ifp; 975 struct sppp *sp = (struct sppp *)ifp;
976 976
977 SPPP_LOCK(sp, RW_WRITER); 977 SPPP_LOCK(sp, RW_WRITER);
978 978
979 switch (ifp->if_link_state) { 979 switch (ifp->if_link_state) {
980 case LINK_STATE_UP: 980 case LINK_STATE_UP:
981 imr->ifm_status = IFM_AVALID | IFM_ACTIVE; 981 imr->ifm_status = IFM_AVALID | IFM_ACTIVE;
982 break; 982 break;
983 case LINK_STATE_DOWN: 983 case LINK_STATE_DOWN:
984 imr->ifm_status = IFM_AVALID; 984 imr->ifm_status = IFM_AVALID;
985 break; 985 break;
986 default: 986 default:
987 /* Should be impossible as we set link state down in attach. */ 987 /* Should be impossible as we set link state down in attach. */
988 imr->ifm_status = 0; 988 imr->ifm_status = 0;
989 break; 989 break;
990 } 990 }
991 991
992 SPPP_UNLOCK(sp); 992 SPPP_UNLOCK(sp);
993} 993}
994 994
995void 995void
996sppp_attach(struct ifnet *ifp) 996sppp_attach(struct ifnet *ifp)
997{ 997{
998 struct sppp *sp = (struct sppp *) ifp; 998 struct sppp *sp = (struct sppp *) ifp;
999 999
1000 /* Initialize keepalive handler. */ 1000 /* Initialize keepalive handler. */
1001 if (! spppq) { 1001 if (! spppq) {
1002 callout_init(&keepalive_ch, CALLOUT_MPSAFE); 1002 callout_init(&keepalive_ch, CALLOUT_MPSAFE);
1003 callout_reset(&keepalive_ch, hz * LCP_KEEPALIVE_INTERVAL, sppp_keepalive, NULL); 1003 callout_reset(&keepalive_ch, hz * LCP_KEEPALIVE_INTERVAL, sppp_keepalive, NULL);
1004 } 1004 }
1005 1005
1006 if (! spppq_lock) 1006 if (! spppq_lock)
1007 spppq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET); 1007 spppq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
1008 1008
1009 /* Insert new entry into the keepalive list. */ 1009 /* Insert new entry into the keepalive list. */
1010 sp->pp_next = spppq; 1010 sp->pp_next = spppq;
1011 spppq = sp; 1011 spppq = sp;
1012 1012
1013 sp->pp_if.if_type = IFT_PPP; 1013 sp->pp_if.if_type = IFT_PPP;
1014 sp->pp_if.if_output = sppp_output; 1014 sp->pp_if.if_output = sppp_output;
1015 sp->pp_fastq.ifq_maxlen = 32; 1015 sp->pp_fastq.ifq_maxlen = 32;
1016 sp->pp_cpq.ifq_maxlen = 20; 1016 sp->pp_cpq.ifq_maxlen = 20;
1017 sp->pp_loopcnt = 0; 1017 sp->pp_loopcnt = 0;
1018 sp->pp_alivecnt = 0; 1018 sp->pp_alivecnt = 0;
1019 sp->pp_last_activity = 0; 1019 sp->pp_last_activity = 0;
1020 sp->pp_last_receive = 0; 1020 sp->pp_last_receive = 0;
1021 sp->pp_maxalive = DEFAULT_MAXALIVECNT; 1021 sp->pp_maxalive = DEFAULT_MAXALIVECNT;
1022 sp->pp_max_noreceive = DEFAULT_NORECV_TIME; 1022 sp->pp_max_noreceive = DEFAULT_NORECV_TIME;
1023 sp->pp_idle_timeout = 0; 1023 sp->pp_idle_timeout = 0;
1024 memset(&sp->pp_seq[0], 0, sizeof(sp->pp_seq)); 1024 memset(&sp->pp_seq[0], 0, sizeof(sp->pp_seq));
1025 memset(&sp->pp_rseq[0], 0, sizeof(sp->pp_rseq)); 1025 memset(&sp->pp_rseq[0], 0, sizeof(sp->pp_rseq));
1026 sp->pp_auth_failures = 0; 1026 sp->pp_auth_failures = 0;
1027 sp->pp_max_auth_fail = DEFAULT_MAX_AUTH_FAILURES; 1027 sp->pp_max_auth_fail = DEFAULT_MAX_AUTH_FAILURES;
1028 sp->pp_phase = SPPP_PHASE_DEAD; 1028 sp->pp_phase = SPPP_PHASE_DEAD;
1029 sp->pp_up = sppp_notify_up; 1029 sp->pp_up = sppp_notify_up;
1030 sp->pp_down = sppp_notify_down; 1030 sp->pp_down = sppp_notify_down;
1031 rw_init(&sp->pp_lock); 1031 rw_init(&sp->pp_lock);
1032 1032
1033 if_alloc_sadl(ifp); 1033 if_alloc_sadl(ifp);
1034 1034
1035 /* Lets not beat about the bush, we know we're down. */ 1035 /* Lets not beat about the bush, we know we're down. */
1036 ifp->if_link_state = LINK_STATE_DOWN; 1036 ifp->if_link_state = LINK_STATE_DOWN;
1037 /* There is no media for PPP, but it's needed to report link status. */ 1037 /* There is no media for PPP, but it's needed to report link status. */
1038 ifmedia_init(&sp->pp_im, 0, sppp_mediachange, sppp_mediastatus); 1038 ifmedia_init(&sp->pp_im, 0, sppp_mediachange, sppp_mediastatus);
1039 1039
1040 memset(&sp->myauth, 0, sizeof sp->myauth); 1040 memset(&sp->myauth, 0, sizeof sp->myauth);
1041 memset(&sp->hisauth, 0, sizeof sp->hisauth); 1041 memset(&sp->hisauth, 0, sizeof sp->hisauth);
1042 SPPP_LOCK(sp, RW_WRITER); 1042 SPPP_LOCK(sp, RW_WRITER);
1043 sppp_lcp_init(sp); 1043 sppp_lcp_init(sp);
1044 sppp_ipcp_init(sp); 1044 sppp_ipcp_init(sp);
1045 sppp_ipv6cp_init(sp); 1045 sppp_ipv6cp_init(sp);
1046 sppp_pap_init(sp); 1046 sppp_pap_init(sp);
1047 sppp_chap_init(sp); 1047 sppp_chap_init(sp);
1048 SPPP_UNLOCK(sp); 1048 SPPP_UNLOCK(sp);
1049} 1049}
1050 1050
1051void 1051void
1052sppp_detach(struct ifnet *ifp) 1052sppp_detach(struct ifnet *ifp)
1053{ 1053{
1054 struct sppp **q, *p, *sp = (struct sppp *) ifp; 1054 struct sppp **q, *p, *sp = (struct sppp *) ifp;
1055 1055
1056 /* Remove the entry from the keepalive list. */ 1056 /* Remove the entry from the keepalive list. */
1057 SPPPQ_LOCK(); 1057 SPPPQ_LOCK();
1058 for (q = &spppq; (p = *q); q = &p->pp_next) 1058 for (q = &spppq; (p = *q); q = &p->pp_next)
1059 if (p == sp) { 1059 if (p == sp) {
1060 *q = p->pp_next; 1060 *q = p->pp_next;
1061 break; 1061 break;
1062 } 1062 }
1063 SPPPQ_UNLOCK(); 1063 SPPPQ_UNLOCK();
1064 1064
1065 if (! spppq) { 1065 if (! spppq) {
1066 /* Stop keepalive handler. */ 1066 /* Stop keepalive handler. */
1067 callout_stop(&keepalive_ch); 1067 callout_stop(&keepalive_ch);
1068 mutex_obj_free(spppq_lock); 1068 mutex_obj_free(spppq_lock);
1069 spppq_lock = NULL; 1069 spppq_lock = NULL;
1070 } 1070 }
1071 1071
1072 SPPP_LOCK(sp, RW_WRITER); 1072 SPPP_LOCK(sp, RW_WRITER);
1073 1073
1074 /* to avoid workqueue enqueued */ 1074 /* to avoid workqueue enqueued */
1075 atomic_swap_uint(&sp->ipcp.update_addrs_enqueued, 1); 1075 atomic_swap_uint(&sp->ipcp.update_addrs_enqueued, 1);
 1076 workqueue_wait(sp->ipcp.update_addrs_wq, &sp->ipcp.update_addrs_wk);
1076 workqueue_destroy(sp->ipcp.update_addrs_wq); 1077 workqueue_destroy(sp->ipcp.update_addrs_wq);
1077 pcq_destroy(sp->ipcp.update_addrs_q); 1078 pcq_destroy(sp->ipcp.update_addrs_q);
1078 1079
1079 callout_stop(&sp->ch[IDX_LCP]); 1080 callout_stop(&sp->ch[IDX_LCP]);
1080 callout_stop(&sp->ch[IDX_IPCP]); 1081 callout_stop(&sp->ch[IDX_IPCP]);
1081 callout_stop(&sp->ch[IDX_PAP]); 1082 callout_stop(&sp->ch[IDX_PAP]);
1082 callout_stop(&sp->ch[IDX_CHAP]); 1083 callout_stop(&sp->ch[IDX_CHAP]);
1083#ifdef INET6 1084#ifdef INET6
1084 callout_stop(&sp->ch[IDX_IPV6CP]); 1085 callout_stop(&sp->ch[IDX_IPV6CP]);
1085#endif 1086#endif
1086 callout_stop(&sp->pap_my_to_ch); 1087 callout_stop(&sp->pap_my_to_ch);
1087 1088
1088 /* free authentication info */ 1089 /* free authentication info */
1089 if (sp->myauth.name) free(sp->myauth.name, M_DEVBUF); 1090 if (sp->myauth.name) free(sp->myauth.name, M_DEVBUF);
1090 if (sp->myauth.secret) free(sp->myauth.secret, M_DEVBUF); 1091 if (sp->myauth.secret) free(sp->myauth.secret, M_DEVBUF);
1091 if (sp->hisauth.name) free(sp->hisauth.name, M_DEVBUF); 1092 if (sp->hisauth.name) free(sp->hisauth.name, M_DEVBUF);
1092 if (sp->hisauth.secret) free(sp->hisauth.secret, M_DEVBUF); 1093 if (sp->hisauth.secret) free(sp->hisauth.secret, M_DEVBUF);
1093 SPPP_UNLOCK(sp); 1094 SPPP_UNLOCK(sp);
1094 rw_destroy(&sp->pp_lock); 1095 rw_destroy(&sp->pp_lock);
1095 1096
1096 /* Safety - shouldn't be needed as there is no media to set. */ 1097 /* Safety - shouldn't be needed as there is no media to set. */
1097 ifmedia_delete_instance(&sp->pp_im, IFM_INST_ANY); 1098 ifmedia_delete_instance(&sp->pp_im, IFM_INST_ANY);
1098} 1099}
1099 1100
1100/* 1101/*
1101 * Flush the interface output queue. 1102 * Flush the interface output queue.
1102 */ 1103 */
1103void 1104void
1104sppp_flush(struct ifnet *ifp) 1105sppp_flush(struct ifnet *ifp)
1105{ 1106{
1106 struct sppp *sp = (struct sppp *) ifp; 1107 struct sppp *sp = (struct sppp *) ifp;
1107 1108
1108 SPPP_LOCK(sp, RW_WRITER); 1109 SPPP_LOCK(sp, RW_WRITER);
1109 IFQ_PURGE(&sp->pp_if.if_snd); 1110 IFQ_PURGE(&sp->pp_if.if_snd);
1110 IF_PURGE(&sp->pp_fastq); 1111 IF_PURGE(&sp->pp_fastq);
1111 IF_PURGE(&sp->pp_cpq); 1112 IF_PURGE(&sp->pp_cpq);
1112 SPPP_UNLOCK(sp); 1113 SPPP_UNLOCK(sp);
1113} 1114}
1114 1115
1115/* 1116/*
1116 * Check if the output queue is empty. 1117 * Check if the output queue is empty.
1117 */ 1118 */
1118int 1119int
1119sppp_isempty(struct ifnet *ifp) 1120sppp_isempty(struct ifnet *ifp)
1120{ 1121{
1121 struct sppp *sp = (struct sppp *) ifp; 1122 struct sppp *sp = (struct sppp *) ifp;
1122 int empty, s; 1123 int empty, s;
1123 1124
1124 s = splnet(); 1125 s = splnet();
1125 SPPP_LOCK(sp, RW_READER); 1126 SPPP_LOCK(sp, RW_READER);
1126 empty = IF_IS_EMPTY(&sp->pp_fastq) && IF_IS_EMPTY(&sp->pp_cpq) && 1127 empty = IF_IS_EMPTY(&sp->pp_fastq) && IF_IS_EMPTY(&sp->pp_cpq) &&
1127 IFQ_IS_EMPTY(&sp->pp_if.if_snd); 1128 IFQ_IS_EMPTY(&sp->pp_if.if_snd);
1128 SPPP_UNLOCK(sp); 1129 SPPP_UNLOCK(sp);
1129 splx(s); 1130 splx(s);
1130 return (empty); 1131 return (empty);
1131} 1132}
1132 1133
1133/* 1134/*
1134 * Get next packet to send. 1135 * Get next packet to send.
1135 */ 1136 */
1136struct mbuf * 1137struct mbuf *
1137sppp_dequeue(struct ifnet *ifp) 1138sppp_dequeue(struct ifnet *ifp)
1138{ 1139{
1139 struct sppp *sp = (struct sppp *) ifp; 1140 struct sppp *sp = (struct sppp *) ifp;
1140 struct mbuf *m; 1141 struct mbuf *m;
1141 int s; 1142 int s;
1142 1143
1143 s = splnet(); 1144 s = splnet();
1144 SPPP_LOCK(sp, RW_WRITER); 1145 SPPP_LOCK(sp, RW_WRITER);
1145 /* 1146 /*
1146 * Process only the control protocol queue until we have at 1147 * Process only the control protocol queue until we have at
1147 * least one NCP open. 1148 * least one NCP open.
1148 * 1149 *
1149 * Do always serve all three queues in Cisco mode. 1150 * Do always serve all three queues in Cisco mode.
1150 */ 1151 */
1151 IF_DEQUEUE(&sp->pp_cpq, m); 1152 IF_DEQUEUE(&sp->pp_cpq, m);
1152 if (m == NULL && 1153 if (m == NULL &&
1153 (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) { 1154 (sppp_ncp_check(sp) || (sp->pp_flags & PP_CISCO) != 0)) {
1154 IF_DEQUEUE(&sp->pp_fastq, m); 1155 IF_DEQUEUE(&sp->pp_fastq, m);
1155 if (m == NULL) 1156 if (m == NULL)
1156 IFQ_DEQUEUE(&sp->pp_if.if_snd, m); 1157 IFQ_DEQUEUE(&sp->pp_if.if_snd, m);
1157 } 1158 }
1158 SPPP_UNLOCK(sp); 1159 SPPP_UNLOCK(sp);
1159 splx(s); 1160 splx(s);
1160 return m; 1161 return m;
1161} 1162}
1162 1163
1163/* 1164/*
1164 * Process an ioctl request. Called on low priority level. 1165 * Process an ioctl request. Called on low priority level.
1165 */ 1166 */
1166int 1167int
1167sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1168sppp_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1168{ 1169{
1169 struct lwp *l = curlwp; /* XXX */ 1170 struct lwp *l = curlwp; /* XXX */
1170 struct ifreq *ifr = (struct ifreq *) data; 1171 struct ifreq *ifr = (struct ifreq *) data;
1171 struct ifaddr *ifa = (struct ifaddr *) data; 1172 struct ifaddr *ifa = (struct ifaddr *) data;
1172 struct sppp *sp = (struct sppp *) ifp; 1173 struct sppp *sp = (struct sppp *) ifp;
1173 int s, error=0, going_up, going_down, newmode; 1174 int s, error=0, going_up, going_down, newmode;
1174 1175
1175 s = splnet(); 1176 s = splnet();
1176 switch (cmd) { 1177 switch (cmd) {
1177 case SIOCINITIFADDR: 1178 case SIOCINITIFADDR:
1178 ifa->ifa_rtrequest = p2p_rtrequest; 1179 ifa->ifa_rtrequest = p2p_rtrequest;
1179 break; 1180 break;
1180 1181
1181 case SIOCSIFFLAGS: 1182 case SIOCSIFFLAGS:
1182 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 1183 if ((error = ifioctl_common(ifp, cmd, data)) != 0)
1183 break; 1184 break;
1184 1185
1185 SPPP_LOCK(sp, RW_WRITER); 1186 SPPP_LOCK(sp, RW_WRITER);
1186 going_up = ifp->if_flags & IFF_UP && 1187 going_up = ifp->if_flags & IFF_UP &&
1187 (ifp->if_flags & IFF_RUNNING) == 0; 1188 (ifp->if_flags & IFF_RUNNING) == 0;
1188 going_down = (ifp->if_flags & IFF_UP) == 0 && 1189 going_down = (ifp->if_flags & IFF_UP) == 0 &&
1189 ifp->if_flags & IFF_RUNNING; 1190 ifp->if_flags & IFF_RUNNING;
1190 newmode = ifp->if_flags & (IFF_AUTO | IFF_PASSIVE); 1191 newmode = ifp->if_flags & (IFF_AUTO | IFF_PASSIVE);
1191 if (newmode == (IFF_AUTO | IFF_PASSIVE)) { 1192 if (newmode == (IFF_AUTO | IFF_PASSIVE)) {
1192 /* sanity */ 1193 /* sanity */
1193 newmode = IFF_PASSIVE; 1194 newmode = IFF_PASSIVE;
1194 ifp->if_flags &= ~IFF_AUTO; 1195 ifp->if_flags &= ~IFF_AUTO;
1195 } 1196 }
1196 1197
1197 if (going_up || going_down) { 1198 if (going_up || going_down) {
1198 lcp.Close(sp); 1199 lcp.Close(sp);
1199 } 1200 }
1200 if (going_up && newmode == 0) { 1201 if (going_up && newmode == 0) {
1201 /* neither auto-dial nor passive */ 1202 /* neither auto-dial nor passive */
1202 ifp->if_flags |= IFF_RUNNING; 1203 ifp->if_flags |= IFF_RUNNING;
1203 if (!(sp->pp_flags & PP_CISCO)) 1204 if (!(sp->pp_flags & PP_CISCO))
1204 lcp.Open(sp); 1205 lcp.Open(sp);
1205 } else if (going_down) { 1206 } else if (going_down) {
1206 SPPP_UNLOCK(sp); 1207 SPPP_UNLOCK(sp);
1207 sppp_flush(ifp); 1208 sppp_flush(ifp);
1208 SPPP_LOCK(sp, RW_WRITER); 1209 SPPP_LOCK(sp, RW_WRITER);
1209 1210
1210 ifp->if_flags &= ~IFF_RUNNING; 1211 ifp->if_flags &= ~IFF_RUNNING;
1211 } 1212 }
1212 SPPP_UNLOCK(sp); 1213 SPPP_UNLOCK(sp);
1213 break; 1214 break;
1214 1215
1215 case SIOCSIFMTU: 1216 case SIOCSIFMTU:
1216 if (ifr->ifr_mtu < PPP_MINMRU || 1217 if (ifr->ifr_mtu < PPP_MINMRU ||
1217 ifr->ifr_mtu > sp->lcp.their_mru) { 1218 ifr->ifr_mtu > sp->lcp.their_mru) {
1218 error = EINVAL; 1219 error = EINVAL;
1219 break; 1220 break;
1220 } 1221 }
1221 /*FALLTHROUGH*/ 1222 /*FALLTHROUGH*/
1222 case SIOCGIFMTU: 1223 case SIOCGIFMTU:
1223 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 1224 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
1224 error = 0; 1225 error = 0;
1225 break; 1226 break;
1226 case SIOCADDMULTI: 1227 case SIOCADDMULTI:
1227 case SIOCDELMULTI: 1228 case SIOCDELMULTI:
1228 break; 1229 break;
1229 1230
1230 case SPPPSETAUTHCFG: 1231 case SPPPSETAUTHCFG:
1231 case SPPPSETLCPCFG: 1232 case SPPPSETLCPCFG:
1232 case SPPPSETIDLETO: 1233 case SPPPSETIDLETO:
1233 case SPPPSETAUTHFAILURE: 1234 case SPPPSETAUTHFAILURE:
1234 case SPPPSETDNSOPTS: 1235 case SPPPSETDNSOPTS:
1235 case SPPPSETKEEPALIVE: 1236 case SPPPSETKEEPALIVE:
1236#if defined(COMPAT_50) || defined(MODULAR) 1237#if defined(COMPAT_50) || defined(MODULAR)
1237 case __SPPPSETIDLETO50: 1238 case __SPPPSETIDLETO50:
1238 case __SPPPSETKEEPALIVE50: 1239 case __SPPPSETKEEPALIVE50:
1239#endif /* COMPAT_50 || MODULAR */ 1240#endif /* COMPAT_50 || MODULAR */
1240 error = kauth_authorize_network(l->l_cred, 1241 error = kauth_authorize_network(l->l_cred,
1241 KAUTH_NETWORK_INTERFACE, 1242 KAUTH_NETWORK_INTERFACE,
1242 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, 1243 KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd,
1243 NULL); 1244 NULL);
1244 if (error) 1245 if (error)
1245 break; 1246 break;
1246 error = sppp_params(sp, cmd, data); 1247 error = sppp_params(sp, cmd, data);
1247 break; 1248 break;
1248 1249
1249 case SPPPGETAUTHCFG: 1250 case SPPPGETAUTHCFG:
1250 case SPPPGETLCPCFG: 1251 case SPPPGETLCPCFG:
1251 case SPPPGETAUTHFAILURES: 1252 case SPPPGETAUTHFAILURES:
1252 error = kauth_authorize_network(l->l_cred, 1253 error = kauth_authorize_network(l->l_cred,
1253 KAUTH_NETWORK_INTERFACE, 1254 KAUTH_NETWORK_INTERFACE,
1254 KAUTH_REQ_NETWORK_INTERFACE_GETPRIV, ifp, (void *)cmd, 1255 KAUTH_REQ_NETWORK_INTERFACE_GETPRIV, ifp, (void *)cmd,
1255 NULL); 1256 NULL);
1256 if (error) 1257 if (error)
1257 break; 1258 break;
1258 error = sppp_params(sp, cmd, data); 1259 error = sppp_params(sp, cmd, data);
1259 break; 1260 break;
1260 1261
1261 case SPPPGETSTATUS: 1262 case SPPPGETSTATUS:
1262 case SPPPGETSTATUSNCP: 1263 case SPPPGETSTATUSNCP:
1263 case SPPPGETIDLETO: 1264 case SPPPGETIDLETO:
1264 case SPPPGETDNSOPTS: 1265 case SPPPGETDNSOPTS:
1265 case SPPPGETDNSADDRS: 1266 case SPPPGETDNSADDRS:
1266 case SPPPGETKEEPALIVE: 1267 case SPPPGETKEEPALIVE:
1267#if defined(COMPAT_50) || defined(MODULAR) 1268#if defined(COMPAT_50) || defined(MODULAR)
1268 case __SPPPGETIDLETO50: 1269 case __SPPPGETIDLETO50:
1269 case __SPPPGETKEEPALIVE50: 1270 case __SPPPGETKEEPALIVE50:
1270#endif /* COMPAT_50 || MODULAR */ 1271#endif /* COMPAT_50 || MODULAR */
1271 error = sppp_params(sp, cmd, data); 1272 error = sppp_params(sp, cmd, data);
1272 break; 1273 break;
1273 1274
1274 case SIOCGIFMEDIA: 1275 case SIOCGIFMEDIA:
1275 error = ifmedia_ioctl(ifp, ifr, &sp->pp_im, cmd); 1276 error = ifmedia_ioctl(ifp, ifr, &sp->pp_im, cmd);
1276 break; 1277 break;
1277 1278
1278 default: 1279 default:
1279 error = ifioctl_common(ifp, cmd, data); 1280 error = ifioctl_common(ifp, cmd, data);
1280 break; 1281 break;
1281 } 1282 }
1282 splx(s); 1283 splx(s);
1283 return (error); 1284 return (error);
1284} 1285}
1285 1286
1286 1287
1287/* 1288/*
1288 * Cisco framing implementation. 1289 * Cisco framing implementation.
1289 */ 1290 */
1290 1291
1291/* 1292/*
1292 * Handle incoming Cisco keepalive protocol packets. 1293 * Handle incoming Cisco keepalive protocol packets.
1293 */ 1294 */
1294static void 1295static void
1295sppp_cisco_input(struct sppp *sp, struct mbuf *m) 1296sppp_cisco_input(struct sppp *sp, struct mbuf *m)
1296{ 1297{
1297 STDDCL; 1298 STDDCL;
1298 struct cisco_packet *h; 1299 struct cisco_packet *h;
1299#ifdef INET 1300#ifdef INET
1300 uint32_t me, mymask = 0; /* XXX: GCC */ 1301 uint32_t me, mymask = 0; /* XXX: GCC */
1301#endif 1302#endif
1302 1303
1303 SPPP_LOCK(sp, RW_WRITER); 1304 SPPP_LOCK(sp, RW_WRITER);
1304 1305
1305 if (m->m_pkthdr.len < CISCO_PACKET_LEN) { 1306 if (m->m_pkthdr.len < CISCO_PACKET_LEN) {
1306 if (debug) 1307 if (debug)
1307 log(LOG_DEBUG, 1308 log(LOG_DEBUG,
1308 "%s: cisco invalid packet length: %d bytes\n", 1309 "%s: cisco invalid packet length: %d bytes\n",
1309 ifp->if_xname, m->m_pkthdr.len); 1310 ifp->if_xname, m->m_pkthdr.len);
1310 SPPP_UNLOCK(sp); 1311 SPPP_UNLOCK(sp);
1311 return; 1312 return;
1312 } 1313 }
1313 h = mtod(m, struct cisco_packet *); 1314 h = mtod(m, struct cisco_packet *);
1314 if (debug) 1315 if (debug)
1315 log(LOG_DEBUG, 1316 log(LOG_DEBUG,
1316 "%s: cisco input: %d bytes " 1317 "%s: cisco input: %d bytes "
1317 "<0x%x 0x%x 0x%x 0x%x 0x%x-0x%x>\n", 1318 "<0x%x 0x%x 0x%x 0x%x 0x%x-0x%x>\n",
1318 ifp->if_xname, m->m_pkthdr.len, 1319 ifp->if_xname, m->m_pkthdr.len,
1319 ntohl(h->type), h->par1, h->par2, (u_int)h->rel, 1320 ntohl(h->type), h->par1, h->par2, (u_int)h->rel,
1320 (u_int)h->time0, (u_int)h->time1); 1321 (u_int)h->time0, (u_int)h->time1);
1321 switch (ntohl(h->type)) { 1322 switch (ntohl(h->type)) {
1322 default: 1323 default:
1323 if (debug) 1324 if (debug)
1324 addlog("%s: cisco unknown packet type: 0x%x\n", 1325 addlog("%s: cisco unknown packet type: 0x%x\n",
1325 ifp->if_xname, ntohl(h->type)); 1326 ifp->if_xname, ntohl(h->type));
1326 break; 1327 break;
1327 case CISCO_ADDR_REPLY: 1328 case CISCO_ADDR_REPLY:
1328 /* Reply on address request, ignore */ 1329 /* Reply on address request, ignore */
1329 break; 1330 break;
1330 case CISCO_KEEPALIVE_REQ: 1331 case CISCO_KEEPALIVE_REQ:
1331 sp->pp_alivecnt = 0; 1332 sp->pp_alivecnt = 0;
1332 sp->pp_rseq[IDX_LCP] = ntohl(h->par1); 1333 sp->pp_rseq[IDX_LCP] = ntohl(h->par1);
1333 if (sp->pp_seq[IDX_LCP] == sp->pp_rseq[IDX_LCP]) { 1334 if (sp->pp_seq[IDX_LCP] == sp->pp_rseq[IDX_LCP]) {
1334 /* Local and remote sequence numbers are equal. 1335 /* Local and remote sequence numbers are equal.
1335 * Probably, the line is in loopback mode. */ 1336 * Probably, the line is in loopback mode. */
1336 if (sp->pp_loopcnt >= LOOPALIVECNT) { 1337 if (sp->pp_loopcnt >= LOOPALIVECNT) {
1337 printf ("%s: loopback\n", 1338 printf ("%s: loopback\n",
1338 ifp->if_xname); 1339 ifp->if_xname);
1339 sp->pp_loopcnt = 0; 1340 sp->pp_loopcnt = 0;
1340 if (ifp->if_flags & IFF_UP) { 1341 if (ifp->if_flags & IFF_UP) {
1341 SPPP_UNLOCK(sp); 1342 SPPP_UNLOCK(sp);
1342 if_down(ifp); 1343 if_down(ifp);
1343 SPPP_LOCK(sp, RW_WRITER); 1344 SPPP_LOCK(sp, RW_WRITER);
1344 1345
1345 IF_PURGE(&sp->pp_cpq); 1346 IF_PURGE(&sp->pp_cpq);
1346 } 1347 }
1347 } 1348 }
1348 ++sp->pp_loopcnt; 1349 ++sp->pp_loopcnt;
1349 1350
1350 /* Generate new local sequence number */ 1351 /* Generate new local sequence number */
1351 sp->pp_seq[IDX_LCP] = cprng_fast32(); 1352 sp->pp_seq[IDX_LCP] = cprng_fast32();
1352 break; 1353 break;
1353 } 1354 }
1354 sp->pp_loopcnt = 0; 1355 sp->pp_loopcnt = 0;
1355 if (! (ifp->if_flags & IFF_UP) && 1356 if (! (ifp->if_flags & IFF_UP) &&
1356 (ifp->if_flags & IFF_RUNNING)) { 1357 (ifp->if_flags & IFF_RUNNING)) {
1357 SPPP_UNLOCK(sp); 1358 SPPP_UNLOCK(sp);
1358 if_up(ifp); 1359 if_up(ifp);
1359 SPPP_LOCK(sp, RW_WRITER); 1360 SPPP_LOCK(sp, RW_WRITER);
1360 } 1361 }
1361 break; 1362 break;
1362 case CISCO_ADDR_REQ: 1363 case CISCO_ADDR_REQ:
1363#ifdef INET 1364#ifdef INET
1364 sppp_get_ip_addrs(sp, &me, 0, &mymask); 1365 sppp_get_ip_addrs(sp, &me, 0, &mymask);
1365 if (me != 0L) 1366 if (me != 0L)
1366 sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask); 1367 sppp_cisco_send(sp, CISCO_ADDR_REPLY, me, mymask);
1367#endif 1368#endif
1368 break; 1369 break;
1369 } 1370 }
1370 SPPP_UNLOCK(sp); 1371 SPPP_UNLOCK(sp);
1371} 1372}
1372 1373
1373/* 1374/*
1374 * Send Cisco keepalive packet. 1375 * Send Cisco keepalive packet.
1375 */ 1376 */
1376static void 1377static void
1377sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2) 1378sppp_cisco_send(struct sppp *sp, int type, int32_t par1, int32_t par2)
1378{ 1379{
1379 STDDCL; 1380 STDDCL;
1380 struct ppp_header *h; 1381 struct ppp_header *h;
1381 struct cisco_packet *ch; 1382 struct cisco_packet *ch;
1382 struct mbuf *m; 1383 struct mbuf *m;
1383 uint32_t t; 1384 uint32_t t;
1384 1385
1385 KASSERT(SPPP_WLOCKED(sp)); 1386 KASSERT(SPPP_WLOCKED(sp));
1386 1387
1387 t = time_uptime * 1000; 1388 t = time_uptime * 1000;
1388 MGETHDR(m, M_DONTWAIT, MT_DATA); 1389 MGETHDR(m, M_DONTWAIT, MT_DATA);
1389 if (! m) 1390 if (! m)
1390 return; 1391 return;
1391 m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN; 1392 m->m_pkthdr.len = m->m_len = PPP_HEADER_LEN + CISCO_PACKET_LEN;
1392 m_reset_rcvif(m); 1393 m_reset_rcvif(m);
1393 1394
1394 h = mtod(m, struct ppp_header *); 1395 h = mtod(m, struct ppp_header *);
1395 h->address = CISCO_MULTICAST; 1396 h->address = CISCO_MULTICAST;
1396 h->control = 0; 1397 h->control = 0;
1397 h->protocol = htons(CISCO_KEEPALIVE); 1398 h->protocol = htons(CISCO_KEEPALIVE);
1398 1399
1399 ch = (struct cisco_packet *)(h + 1); 1400 ch = (struct cisco_packet *)(h + 1);
1400 ch->type = htonl(type); 1401 ch->type = htonl(type);
1401 ch->par1 = htonl(par1); 1402 ch->par1 = htonl(par1);
1402 ch->par2 = htonl(par2); 1403 ch->par2 = htonl(par2);
1403 ch->rel = -1; 1404 ch->rel = -1;
1404 1405
1405 ch->time0 = htons((u_short)(t >> 16)); 1406 ch->time0 = htons((u_short)(t >> 16));
1406 ch->time1 = htons((u_short) t); 1407 ch->time1 = htons((u_short) t);
1407 1408
1408 if (debug) 1409 if (debug)
1409 log(LOG_DEBUG, 1410 log(LOG_DEBUG,
1410 "%s: cisco output: <0x%x 0x%x 0x%x 0x%x 0x%x-0x%x>\n", 1411 "%s: cisco output: <0x%x 0x%x 0x%x 0x%x 0x%x-0x%x>\n",
1411 ifp->if_xname, ntohl(ch->type), ch->par1, 1412 ifp->if_xname, ntohl(ch->type), ch->par1,
1412 ch->par2, (u_int)ch->rel, (u_int)ch->time0, 1413 ch->par2, (u_int)ch->rel, (u_int)ch->time0,
1413 (u_int)ch->time1); 1414 (u_int)ch->time1);
1414 1415
1415 if (IF_QFULL(&sp->pp_cpq)) { 1416 if (IF_QFULL(&sp->pp_cpq)) {
1416 IF_DROP(&sp->pp_fastq); 1417 IF_DROP(&sp->pp_fastq);
1417 IF_DROP(&ifp->if_snd); 1418 IF_DROP(&ifp->if_snd);
1418 m_freem(m); 1419 m_freem(m);
1419 ++ifp->if_oerrors; 1420 ++ifp->if_oerrors;
1420 return; 1421 return;
1421 } 1422 }
1422 1423
1423 ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; 1424 ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes;
1424 IF_ENQUEUE(&sp->pp_cpq, m); 1425 IF_ENQUEUE(&sp->pp_cpq, m);
1425 1426
1426 if (! (ifp->if_flags & IFF_OACTIVE)) { 1427 if (! (ifp->if_flags & IFF_OACTIVE)) {
1427 SPPP_UNLOCK(sp); 1428 SPPP_UNLOCK(sp);
1428 if_start_lock(ifp); 1429 if_start_lock(ifp);
1429 SPPP_LOCK(sp, RW_WRITER); 1430 SPPP_LOCK(sp, RW_WRITER);
1430 } 1431 }
1431} 1432}
1432 1433
1433/* 1434/*
1434 * PPP protocol implementation. 1435 * PPP protocol implementation.
1435 */ 1436 */
1436 1437
1437/* 1438/*
1438 * Send PPP control protocol packet. 1439 * Send PPP control protocol packet.
1439 */ 1440 */
1440static void 1441static void
1441sppp_cp_send(struct sppp *sp, u_short proto, u_char type, 1442sppp_cp_send(struct sppp *sp, u_short proto, u_char type,
1442 u_char ident, u_short len, void *data) 1443 u_char ident, u_short len, void *data)
1443{ 1444{
1444 STDDCL; 1445 STDDCL;
1445 struct lcp_header *lh; 1446 struct lcp_header *lh;
1446 struct mbuf *m; 1447 struct mbuf *m;
1447 size_t pkthdrlen; 1448 size_t pkthdrlen;
1448 1449
1449 KASSERT(SPPP_WLOCKED(sp)); 1450 KASSERT(SPPP_WLOCKED(sp));
1450 1451
1451 pkthdrlen = (sp->pp_flags & PP_NOFRAMING) ? 2 : PPP_HEADER_LEN; 1452 pkthdrlen = (sp->pp_flags & PP_NOFRAMING) ? 2 : PPP_HEADER_LEN;
1452 1453
1453 if (len > MHLEN - pkthdrlen - LCP_HEADER_LEN) 1454 if (len > MHLEN - pkthdrlen - LCP_HEADER_LEN)
1454 len = MHLEN - pkthdrlen - LCP_HEADER_LEN; 1455 len = MHLEN - pkthdrlen - LCP_HEADER_LEN;
1455 MGETHDR(m, M_DONTWAIT, MT_DATA); 1456 MGETHDR(m, M_DONTWAIT, MT_DATA);
1456 if (! m) { 1457 if (! m) {
1457 return; 1458 return;
1458 } 1459 }
1459 m->m_pkthdr.len = m->m_len = pkthdrlen + LCP_HEADER_LEN + len; 1460 m->m_pkthdr.len = m->m_len = pkthdrlen + LCP_HEADER_LEN + len;
1460 m_reset_rcvif(m); 1461 m_reset_rcvif(m);
1461 1462
1462 if (sp->pp_flags & PP_NOFRAMING) { 1463 if (sp->pp_flags & PP_NOFRAMING) {
1463 *mtod(m, uint16_t *) = htons(proto); 1464 *mtod(m, uint16_t *) = htons(proto);
1464 lh = (struct lcp_header *)(mtod(m, uint8_t *) + 2); 1465 lh = (struct lcp_header *)(mtod(m, uint8_t *) + 2);
1465 } else { 1466 } else {
1466 struct ppp_header *h; 1467 struct ppp_header *h;
1467 h = mtod(m, struct ppp_header *); 1468 h = mtod(m, struct ppp_header *);
1468 h->address = PPP_ALLSTATIONS; /* broadcast address */ 1469 h->address = PPP_ALLSTATIONS; /* broadcast address */
1469 h->control = PPP_UI; /* Unnumbered Info */ 1470 h->control = PPP_UI; /* Unnumbered Info */
1470 h->protocol = htons(proto); /* Link Control Protocol */ 1471 h->protocol = htons(proto); /* Link Control Protocol */
1471 lh = (struct lcp_header *)(h + 1); 1472 lh = (struct lcp_header *)(h + 1);
1472 } 1473 }
1473 lh->type = type; 1474 lh->type = type;
1474 lh->ident = ident; 1475 lh->ident = ident;
1475 lh->len = htons(LCP_HEADER_LEN + len); 1476 lh->len = htons(LCP_HEADER_LEN + len);
1476 if (len) 1477 if (len)
1477 memcpy(lh + 1, data, len); 1478 memcpy(lh + 1, data, len);
1478 1479
1479 if (debug) { 1480 if (debug) {
1480 log(LOG_DEBUG, "%s: %s output <%s id=0x%x len=%d", 1481 log(LOG_DEBUG, "%s: %s output <%s id=0x%x len=%d",
1481 ifp->if_xname, 1482 ifp->if_xname,
1482 sppp_proto_name(proto), 1483 sppp_proto_name(proto),
1483 sppp_cp_type_name(lh->type), lh->ident, ntohs(lh->len)); 1484 sppp_cp_type_name(lh->type), lh->ident, ntohs(lh->len));
1484 if (len) 1485 if (len)
1485 sppp_print_bytes((u_char *)(lh + 1), len); 1486 sppp_print_bytes((u_char *)(lh + 1), len);
1486 addlog(">\n"); 1487 addlog(">\n");
1487 } 1488 }
1488 if (IF_QFULL(&sp->pp_cpq)) { 1489 if (IF_QFULL(&sp->pp_cpq)) {
1489 IF_DROP(&sp->pp_fastq); 1490 IF_DROP(&sp->pp_fastq);
1490 IF_DROP(&ifp->if_snd); 1491 IF_DROP(&ifp->if_snd);
1491 m_freem(m); 1492 m_freem(m);
1492 ++ifp->if_oerrors; 1493 ++ifp->if_oerrors;
1493 return; 1494 return;
1494 } 1495 }
1495 1496
1496 ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes; 1497 ifp->if_obytes += m->m_pkthdr.len + sp->pp_framebytes;
1497 IF_ENQUEUE(&sp->pp_cpq, m); 1498 IF_ENQUEUE(&sp->pp_cpq, m);
1498 1499
1499 1500
1500 if (! (ifp->if_flags & IFF_OACTIVE)) { 1501 if (! (ifp->if_flags & IFF_OACTIVE)) {
1501 SPPP_UNLOCK(sp); 1502 SPPP_UNLOCK(sp);
1502 if_start_lock(ifp); 1503 if_start_lock(ifp);
1503 SPPP_LOCK(sp, RW_WRITER); 1504 SPPP_LOCK(sp, RW_WRITER);
1504 } 1505 }
1505} 1506}
1506 1507
1507/* 1508/*
1508 * Handle incoming PPP control protocol packets. 1509 * Handle incoming PPP control protocol packets.
1509 */ 1510 */
1510static void 1511static void
1511sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m) 1512sppp_cp_input(const struct cp *cp, struct sppp *sp, struct mbuf *m)
1512{ 1513{
1513 STDDCL; 1514 STDDCL;
1514 struct lcp_header *h; 1515 struct lcp_header *h;
1515 int printlen, len = m->m_pkthdr.len; 1516 int printlen, len = m->m_pkthdr.len;
1516 int rv; 1517 int rv;
1517 u_char *p; 1518 u_char *p;
1518 uint32_t u32; 1519 uint32_t u32;
1519 1520
1520 SPPP_LOCK(sp, RW_WRITER); 1521 SPPP_LOCK(sp, RW_WRITER);
1521 1522
1522 if (len < 4) { 1523 if (len < 4) {
1523 if (debug) 1524 if (debug)
1524 log(LOG_DEBUG, 1525 log(LOG_DEBUG,
1525 "%s: %s invalid packet length: %d bytes\n", 1526 "%s: %s invalid packet length: %d bytes\n",
1526 ifp->if_xname, cp->name, len); 1527 ifp->if_xname, cp->name, len);
1527 SPPP_UNLOCK(sp); 1528 SPPP_UNLOCK(sp);
1528 return; 1529 return;
1529 } 1530 }
1530 h = mtod(m, struct lcp_header *); 1531 h = mtod(m, struct lcp_header *);
1531 if (debug) { 1532 if (debug) {
1532 printlen = ntohs(h->len); 1533 printlen = ntohs(h->len);
1533 log(LOG_DEBUG, 1534 log(LOG_DEBUG,
1534 "%s: %s input(%s): <%s id=0x%x len=%d", 1535 "%s: %s input(%s): <%s id=0x%x len=%d",
1535 ifp->if_xname, cp->name, 1536 ifp->if_xname, cp->name,
1536 sppp_state_name(sp->state[cp->protoidx]), 1537 sppp_state_name(sp->state[cp->protoidx]),
1537 sppp_cp_type_name(h->type), h->ident, printlen); 1538 sppp_cp_type_name(h->type), h->ident, printlen);
1538 if (len < printlen) 1539 if (len < printlen)
1539 printlen = len; 1540 printlen = len;
1540 if (printlen > 4) 1541 if (printlen > 4)
1541 sppp_print_bytes((u_char *)(h + 1), printlen - 4); 1542 sppp_print_bytes((u_char *)(h + 1), printlen - 4);
1542 addlog(">\n"); 1543 addlog(">\n");
1543 } 1544 }
1544 if (len > ntohs(h->len)) 1545 if (len > ntohs(h->len))
1545 len = ntohs(h->len); 1546 len = ntohs(h->len);
1546 p = (u_char *)(h + 1); 1547 p = (u_char *)(h + 1);
1547 switch (h->type) { 1548 switch (h->type) {
1548 case CONF_REQ: 1549 case CONF_REQ:
1549 if (len < 4) { 1550 if (len < 4) {
1550 if (debug) 1551 if (debug)
1551 addlog("%s: %s invalid conf-req length %d\n", 1552 addlog("%s: %s invalid conf-req length %d\n",
1552 ifp->if_xname, cp->name, 1553 ifp->if_xname, cp->name,
1553 len); 1554 len);
1554 ++ifp->if_ierrors; 1555 ++ifp->if_ierrors;
1555 break; 1556 break;
1556 } 1557 }
1557 /* handle states where RCR doesn't get a SCA/SCN */ 1558 /* handle states where RCR doesn't get a SCA/SCN */
1558 switch (sp->state[cp->protoidx]) { 1559 switch (sp->state[cp->protoidx]) {
1559 case STATE_CLOSING: 1560 case STATE_CLOSING:
1560 case STATE_STOPPING: 1561 case STATE_STOPPING:
1561 SPPP_UNLOCK(sp); 1562 SPPP_UNLOCK(sp);
1562 return; 1563 return;
1563 case STATE_CLOSED: 1564 case STATE_CLOSED:
1564 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 1565 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident,
1565 0, 0); 1566 0, 0);
1566 SPPP_UNLOCK(sp); 1567 SPPP_UNLOCK(sp);
1567 return; 1568 return;
1568 } 1569 }
1569 rv = (cp->RCR)(sp, h, len); 1570 rv = (cp->RCR)(sp, h, len);
1570 if (rv < 0) { 1571 if (rv < 0) {
1571 /* fatal error, shut down */ 1572 /* fatal error, shut down */
1572 (cp->tld)(sp); 1573 (cp->tld)(sp);
1573 sppp_lcp_tlf(sp); 1574 sppp_lcp_tlf(sp);
1574 SPPP_UNLOCK(sp); 1575 SPPP_UNLOCK(sp);
1575 return; 1576 return;
1576 } 1577 }
1577 switch (sp->state[cp->protoidx]) { 1578 switch (sp->state[cp->protoidx]) {
1578 case STATE_OPENED: 1579 case STATE_OPENED:
1579 (cp->tld)(sp); 1580 (cp->tld)(sp);
1580 (cp->scr)(sp); 1581 (cp->scr)(sp);
1581 /* fall through... */ 1582 /* fall through... */
1582 case STATE_ACK_SENT: 1583 case STATE_ACK_SENT:
1583 case STATE_REQ_SENT: 1584 case STATE_REQ_SENT:
1584 sppp_cp_change_state(cp, sp, rv? 1585 sppp_cp_change_state(cp, sp, rv?
1585 STATE_ACK_SENT: STATE_REQ_SENT); 1586 STATE_ACK_SENT: STATE_REQ_SENT);
1586 break; 1587 break;
1587 case STATE_STOPPED: 1588 case STATE_STOPPED:
1588 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1589 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
1589 (cp->scr)(sp); 1590 (cp->scr)(sp);
1590 sppp_cp_change_state(cp, sp, rv? 1591 sppp_cp_change_state(cp, sp, rv?
1591 STATE_ACK_SENT: STATE_REQ_SENT); 1592 STATE_ACK_SENT: STATE_REQ_SENT);
1592 break; 1593 break;
1593 case STATE_ACK_RCVD: 1594 case STATE_ACK_RCVD:
1594 if (rv) { 1595 if (rv) {
1595 sppp_cp_change_state(cp, sp, STATE_OPENED); 1596 sppp_cp_change_state(cp, sp, STATE_OPENED);
1596 if (debug) 1597 if (debug)
1597 log(LOG_DEBUG, "%s: %s tlu\n", 1598 log(LOG_DEBUG, "%s: %s tlu\n",
1598 ifp->if_xname, 1599 ifp->if_xname,
1599 cp->name); 1600 cp->name);
1600 (cp->tlu)(sp); 1601 (cp->tlu)(sp);
1601 } else 1602 } else
1602 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1603 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
1603 break; 1604 break;
1604 default: 1605 default:
1605 printf("%s: %s illegal %s in state %s\n", 1606 printf("%s: %s illegal %s in state %s\n",
1606 ifp->if_xname, cp->name, 1607 ifp->if_xname, cp->name,
1607 sppp_cp_type_name(h->type), 1608 sppp_cp_type_name(h->type),
1608 sppp_state_name(sp->state[cp->protoidx])); 1609 sppp_state_name(sp->state[cp->protoidx]));
1609 ++ifp->if_ierrors; 1610 ++ifp->if_ierrors;
1610 } 1611 }
1611 break; 1612 break;
1612 case CONF_ACK: 1613 case CONF_ACK:
1613 if (h->ident != sp->confid[cp->protoidx]) { 1614 if (h->ident != sp->confid[cp->protoidx]) {
1614 if (debug) 1615 if (debug)
1615 addlog("%s: %s id mismatch 0x%x != 0x%x\n", 1616 addlog("%s: %s id mismatch 0x%x != 0x%x\n",
1616 ifp->if_xname, cp->name, 1617 ifp->if_xname, cp->name,
1617 h->ident, sp->confid[cp->protoidx]); 1618 h->ident, sp->confid[cp->protoidx]);
1618 ++ifp->if_ierrors; 1619 ++ifp->if_ierrors;
1619 break; 1620 break;
1620 } 1621 }
1621 switch (sp->state[cp->protoidx]) { 1622 switch (sp->state[cp->protoidx]) {
1622 case STATE_CLOSED: 1623 case STATE_CLOSED:
1623 case STATE_STOPPED: 1624 case STATE_STOPPED:
1624 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1625 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
1625 break; 1626 break;
1626 case STATE_CLOSING: 1627 case STATE_CLOSING:
1627 case STATE_STOPPING: 1628 case STATE_STOPPING:
1628 break; 1629 break;
1629 case STATE_REQ_SENT: 1630 case STATE_REQ_SENT:
1630 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1631 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
1631 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1632 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
1632 break; 1633 break;
1633 case STATE_OPENED: 1634 case STATE_OPENED:
1634 (cp->tld)(sp); 1635 (cp->tld)(sp);
1635 /* fall through */ 1636 /* fall through */
1636 case STATE_ACK_RCVD: 1637 case STATE_ACK_RCVD:
1637 (cp->scr)(sp); 1638 (cp->scr)(sp);
1638 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1639 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1639 break; 1640 break;
1640 case STATE_ACK_SENT: 1641 case STATE_ACK_SENT:
1641 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1642 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
1642 sppp_cp_change_state(cp, sp, STATE_OPENED); 1643 sppp_cp_change_state(cp, sp, STATE_OPENED);
1643 if (debug) 1644 if (debug)
1644 log(LOG_DEBUG, "%s: %s tlu\n", 1645 log(LOG_DEBUG, "%s: %s tlu\n",
1645 ifp->if_xname, cp->name); 1646 ifp->if_xname, cp->name);
1646 (cp->tlu)(sp); 1647 (cp->tlu)(sp);
1647 break; 1648 break;
1648 default: 1649 default:
1649 printf("%s: %s illegal %s in state %s\n", 1650 printf("%s: %s illegal %s in state %s\n",
1650 ifp->if_xname, cp->name, 1651 ifp->if_xname, cp->name,
1651 sppp_cp_type_name(h->type), 1652 sppp_cp_type_name(h->type),
1652 sppp_state_name(sp->state[cp->protoidx])); 1653 sppp_state_name(sp->state[cp->protoidx]));
1653 ++ifp->if_ierrors; 1654 ++ifp->if_ierrors;
1654 } 1655 }
1655 break; 1656 break;
1656 case CONF_NAK: 1657 case CONF_NAK:
1657 case CONF_REJ: 1658 case CONF_REJ:
1658 if (h->ident != sp->confid[cp->protoidx]) { 1659 if (h->ident != sp->confid[cp->protoidx]) {
1659 if (debug) 1660 if (debug)
1660 addlog("%s: %s id mismatch 0x%x != 0x%x\n", 1661 addlog("%s: %s id mismatch 0x%x != 0x%x\n",
1661 ifp->if_xname, cp->name, 1662 ifp->if_xname, cp->name,
1662 h->ident, sp->confid[cp->protoidx]); 1663 h->ident, sp->confid[cp->protoidx]);
1663 ++ifp->if_ierrors; 1664 ++ifp->if_ierrors;
1664 break; 1665 break;
1665 } 1666 }
1666 if (h->type == CONF_NAK) 1667 if (h->type == CONF_NAK)
1667 (cp->RCN_nak)(sp, h, len); 1668 (cp->RCN_nak)(sp, h, len);
1668 else /* CONF_REJ */ 1669 else /* CONF_REJ */
1669 (cp->RCN_rej)(sp, h, len); 1670 (cp->RCN_rej)(sp, h, len);
1670 1671
1671 switch (sp->state[cp->protoidx]) { 1672 switch (sp->state[cp->protoidx]) {
1672 case STATE_CLOSED: 1673 case STATE_CLOSED:
1673 case STATE_STOPPED: 1674 case STATE_STOPPED:
1674 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1675 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
1675 break; 1676 break;
1676 case STATE_REQ_SENT: 1677 case STATE_REQ_SENT:
1677 case STATE_ACK_SENT: 1678 case STATE_ACK_SENT:
1678 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1679 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
1679 (cp->scr)(sp); 1680 (cp->scr)(sp);
1680 break; 1681 break;
1681 case STATE_OPENED: 1682 case STATE_OPENED:
1682 (cp->tld)(sp); 1683 (cp->tld)(sp);
1683 /* fall through */ 1684 /* fall through */
1684 case STATE_ACK_RCVD: 1685 case STATE_ACK_RCVD:
1685 sppp_cp_change_state(cp, sp, STATE_ACK_SENT); 1686 sppp_cp_change_state(cp, sp, STATE_ACK_SENT);
1686 (cp->scr)(sp); 1687 (cp->scr)(sp);
1687 break; 1688 break;
1688 case STATE_CLOSING: 1689 case STATE_CLOSING:
1689 case STATE_STOPPING: 1690 case STATE_STOPPING:
1690 break; 1691 break;
1691 default: 1692 default:
1692 printf("%s: %s illegal %s in state %s\n", 1693 printf("%s: %s illegal %s in state %s\n",
1693 ifp->if_xname, cp->name, 1694 ifp->if_xname, cp->name,
1694 sppp_cp_type_name(h->type), 1695 sppp_cp_type_name(h->type),
1695 sppp_state_name(sp->state[cp->protoidx])); 1696 sppp_state_name(sp->state[cp->protoidx]));
1696 ++ifp->if_ierrors; 1697 ++ifp->if_ierrors;
1697 } 1698 }
1698 break; 1699 break;
1699 1700
1700 case TERM_REQ: 1701 case TERM_REQ:
1701 switch (sp->state[cp->protoidx]) { 1702 switch (sp->state[cp->protoidx]) {
1702 case STATE_ACK_RCVD: 1703 case STATE_ACK_RCVD:
1703 case STATE_ACK_SENT: 1704 case STATE_ACK_SENT:
1704 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1705 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1705 /* fall through */ 1706 /* fall through */
1706 case STATE_CLOSED: 1707 case STATE_CLOSED:
1707 case STATE_STOPPED: 1708 case STATE_STOPPED:
1708 case STATE_CLOSING: 1709 case STATE_CLOSING:
1709 case STATE_STOPPING: 1710 case STATE_STOPPING:
1710 case STATE_REQ_SENT: 1711 case STATE_REQ_SENT:
1711 sta: 1712 sta:
1712 /* Send Terminate-Ack packet. */ 1713 /* Send Terminate-Ack packet. */
1713 if (debug) 1714 if (debug)
1714 log(LOG_DEBUG, "%s: %s send terminate-ack\n", 1715 log(LOG_DEBUG, "%s: %s send terminate-ack\n",
1715 ifp->if_xname, cp->name); 1716 ifp->if_xname, cp->name);
1716 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0); 1717 sppp_cp_send(sp, cp->proto, TERM_ACK, h->ident, 0, 0);
1717 break; 1718 break;
1718 case STATE_OPENED: 1719 case STATE_OPENED:
1719 (cp->tld)(sp); 1720 (cp->tld)(sp);
1720 sp->rst_counter[cp->protoidx] = 0; 1721 sp->rst_counter[cp->protoidx] = 0;
1721 sppp_cp_change_state(cp, sp, STATE_STOPPING); 1722 sppp_cp_change_state(cp, sp, STATE_STOPPING);
1722 goto sta; 1723 goto sta;
1723 default: 1724 default:
1724 printf("%s: %s illegal %s in state %s\n", 1725 printf("%s: %s illegal %s in state %s\n",
1725 ifp->if_xname, cp->name, 1726 ifp->if_xname, cp->name,
1726 sppp_cp_type_name(h->type), 1727 sppp_cp_type_name(h->type),
1727 sppp_state_name(sp->state[cp->protoidx])); 1728 sppp_state_name(sp->state[cp->protoidx]));
1728 ++ifp->if_ierrors; 1729 ++ifp->if_ierrors;
1729 } 1730 }
1730 break; 1731 break;
1731 case TERM_ACK: 1732 case TERM_ACK:
1732 switch (sp->state[cp->protoidx]) { 1733 switch (sp->state[cp->protoidx]) {
1733 case STATE_CLOSED: 1734 case STATE_CLOSED:
1734 case STATE_STOPPED: 1735 case STATE_STOPPED:
1735 case STATE_REQ_SENT: 1736 case STATE_REQ_SENT:
1736 case STATE_ACK_SENT: 1737 case STATE_ACK_SENT:
1737 break; 1738 break;
1738 case STATE_CLOSING: 1739 case STATE_CLOSING:
1739 (cp->tlf)(sp); 1740 (cp->tlf)(sp);
1740 sppp_cp_change_state(cp, sp, STATE_CLOSED); 1741 sppp_cp_change_state(cp, sp, STATE_CLOSED);
1741 sppp_lcp_check_and_close(sp); 1742 sppp_lcp_check_and_close(sp);
1742 break; 1743 break;
1743 case STATE_STOPPING: 1744 case STATE_STOPPING:
1744 (cp->tlf)(sp); 1745 (cp->tlf)(sp);
1745 sppp_cp_change_state(cp, sp, STATE_STOPPED); 1746 sppp_cp_change_state(cp, sp, STATE_STOPPED);
1746 sppp_lcp_check_and_close(sp); 1747 sppp_lcp_check_and_close(sp);
1747 break; 1748 break;
1748 case STATE_ACK_RCVD: 1749 case STATE_ACK_RCVD:
1749 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1750 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1750 break; 1751 break;
1751 case STATE_OPENED: 1752 case STATE_OPENED:
1752 (cp->tld)(sp); 1753 (cp->tld)(sp);
1753 (cp->scr)(sp); 1754 (cp->scr)(sp);
1754 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD); 1755 sppp_cp_change_state(cp, sp, STATE_ACK_RCVD);
1755 break; 1756 break;
1756 default: 1757 default:
1757 printf("%s: %s illegal %s in state %s\n", 1758 printf("%s: %s illegal %s in state %s\n",
1758 ifp->if_xname, cp->name, 1759 ifp->if_xname, cp->name,
1759 sppp_cp_type_name(h->type), 1760 sppp_cp_type_name(h->type),
1760 sppp_state_name(sp->state[cp->protoidx])); 1761 sppp_state_name(sp->state[cp->protoidx]));
1761 ++ifp->if_ierrors; 1762 ++ifp->if_ierrors;
1762 } 1763 }
1763 break; 1764 break;
1764 case CODE_REJ: 1765 case CODE_REJ:
1765 /* XXX catastrophic rejects (RXJ-) aren't handled yet. */ 1766 /* XXX catastrophic rejects (RXJ-) aren't handled yet. */
1766 log(LOG_INFO, 1767 log(LOG_INFO,
1767 "%s: %s: ignoring RXJ (%s) for code ?, " 1768 "%s: %s: ignoring RXJ (%s) for code ?, "
1768 "danger will robinson\n", 1769 "danger will robinson\n",
1769 ifp->if_xname, cp->name, 1770 ifp->if_xname, cp->name,
1770 sppp_cp_type_name(h->type)); 1771 sppp_cp_type_name(h->type));
1771 switch (sp->state[cp->protoidx]) { 1772 switch (sp->state[cp->protoidx]) {
1772 case STATE_CLOSED: 1773 case STATE_CLOSED:
1773 case STATE_STOPPED: 1774 case STATE_STOPPED:
1774 case STATE_REQ_SENT: 1775 case STATE_REQ_SENT:
1775 case STATE_ACK_SENT: 1776 case STATE_ACK_SENT:
1776 case STATE_CLOSING: 1777 case STATE_CLOSING:
1777 case STATE_STOPPING: 1778 case STATE_STOPPING:
1778 case STATE_OPENED: 1779 case STATE_OPENED:
1779 break; 1780 break;
1780 case STATE_ACK_RCVD: 1781 case STATE_ACK_RCVD:
1781 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1782 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1782 break; 1783 break;
1783 default: 1784 default:
1784 printf("%s: %s illegal %s in state %s\n", 1785 printf("%s: %s illegal %s in state %s\n",
1785 ifp->if_xname, cp->name, 1786 ifp->if_xname, cp->name,
1786 sppp_cp_type_name(h->type), 1787 sppp_cp_type_name(h->type),
1787 sppp_state_name(sp->state[cp->protoidx])); 1788 sppp_state_name(sp->state[cp->protoidx]));
1788 ++ifp->if_ierrors; 1789 ++ifp->if_ierrors;
1789 } 1790 }
1790 break; 1791 break;
1791 case PROTO_REJ: 1792 case PROTO_REJ:
1792 { 1793 {
1793 int catastrophic; 1794 int catastrophic;
1794 const struct cp *upper; 1795 const struct cp *upper;
1795 int i; 1796 int i;
1796 uint16_t proto; 1797 uint16_t proto;
1797 1798
1798 catastrophic = 0; 1799 catastrophic = 0;
1799 upper = NULL; 1800 upper = NULL;
1800 proto = p[0] << 8 | p[1]; 1801 proto = p[0] << 8 | p[1];
1801 for (i = 0; i < IDX_COUNT; i++) { 1802 for (i = 0; i < IDX_COUNT; i++) {
1802 if (cps[i]->proto == proto) { 1803 if (cps[i]->proto == proto) {
1803 upper = cps[i]; 1804 upper = cps[i];
1804 break; 1805 break;
1805 } 1806 }
1806 } 1807 }
1807 if (upper == NULL) 1808 if (upper == NULL)
1808 catastrophic++; 1809 catastrophic++;
1809 1810
1810 if (debug) 1811 if (debug)
1811 log(LOG_INFO, 1812 log(LOG_INFO,
1812 "%s: %s: RXJ%c (%s) for proto 0x%x (%s/%s)\n", 1813 "%s: %s: RXJ%c (%s) for proto 0x%x (%s/%s)\n",
1813 ifp->if_xname, cp->name, catastrophic ? '-' : '+', 1814 ifp->if_xname, cp->name, catastrophic ? '-' : '+',
1814 sppp_cp_type_name(h->type), proto, 1815 sppp_cp_type_name(h->type), proto,
1815 upper ? upper->name : "unknown", 1816 upper ? upper->name : "unknown",
1816 upper ? sppp_state_name(sp->state[upper->protoidx]) : "?"); 1817 upper ? sppp_state_name(sp->state[upper->protoidx]) : "?");
1817 1818
1818 /* 1819 /*
1819 * if we got RXJ+ against conf-req, the peer does not implement 1820 * if we got RXJ+ against conf-req, the peer does not implement
1820 * this particular protocol type. terminate the protocol. 1821 * this particular protocol type. terminate the protocol.
1821 */ 1822 */
1822 if (upper && !catastrophic) { 1823 if (upper && !catastrophic) {
1823 if (sp->state[upper->protoidx] == STATE_REQ_SENT) { 1824 if (sp->state[upper->protoidx] == STATE_REQ_SENT) {
1824 upper->Close(sp); 1825 upper->Close(sp);
1825 break; 1826 break;
1826 } 1827 }
1827 } 1828 }
1828 1829
1829 /* XXX catastrophic rejects (RXJ-) aren't handled yet. */ 1830 /* XXX catastrophic rejects (RXJ-) aren't handled yet. */
1830 switch (sp->state[cp->protoidx]) { 1831 switch (sp->state[cp->protoidx]) {
1831 case STATE_CLOSED: 1832 case STATE_CLOSED:
1832 case STATE_STOPPED: 1833 case STATE_STOPPED:
1833 case STATE_REQ_SENT: 1834 case STATE_REQ_SENT:
1834 case STATE_ACK_SENT: 1835 case STATE_ACK_SENT:
1835 case STATE_CLOSING: 1836 case STATE_CLOSING:
1836 case STATE_STOPPING: 1837 case STATE_STOPPING:
1837 case STATE_OPENED: 1838 case STATE_OPENED:
1838 break; 1839 break;
1839 case STATE_ACK_RCVD: 1840 case STATE_ACK_RCVD:
1840 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1841 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1841 break; 1842 break;
1842 default: 1843 default:
1843 printf("%s: %s illegal %s in state %s\n", 1844 printf("%s: %s illegal %s in state %s\n",
1844 ifp->if_xname, cp->name, 1845 ifp->if_xname, cp->name,
1845 sppp_cp_type_name(h->type), 1846 sppp_cp_type_name(h->type),
1846 sppp_state_name(sp->state[cp->protoidx])); 1847 sppp_state_name(sp->state[cp->protoidx]));
1847 ++ifp->if_ierrors; 1848 ++ifp->if_ierrors;
1848 } 1849 }
1849 break; 1850 break;
1850 } 1851 }
1851 case DISC_REQ: 1852 case DISC_REQ:
1852 if (cp->proto != PPP_LCP) 1853 if (cp->proto != PPP_LCP)
1853 goto illegal; 1854 goto illegal;
1854 /* Discard the packet. */ 1855 /* Discard the packet. */
1855 break; 1856 break;
1856 case ECHO_REQ: 1857 case ECHO_REQ:
1857 if (cp->proto != PPP_LCP) 1858 if (cp->proto != PPP_LCP)
1858 goto illegal; 1859 goto illegal;
1859 if (sp->state[cp->protoidx] != STATE_OPENED) { 1860 if (sp->state[cp->protoidx] != STATE_OPENED) {
1860 if (debug) 1861 if (debug)
1861 addlog("%s: lcp echo req but lcp closed\n", 1862 addlog("%s: lcp echo req but lcp closed\n",
1862 ifp->if_xname); 1863 ifp->if_xname);
1863 ++ifp->if_ierrors; 1864 ++ifp->if_ierrors;
1864 break; 1865 break;
1865 } 1866 }
1866 if (len < 8) { 1867 if (len < 8) {
1867 if (debug) 1868 if (debug)
1868 addlog("%s: invalid lcp echo request " 1869 addlog("%s: invalid lcp echo request "
1869 "packet length: %d bytes\n", 1870 "packet length: %d bytes\n",
1870 ifp->if_xname, len); 1871 ifp->if_xname, len);
1871 break; 1872 break;
1872 } 1873 }
1873 memcpy(&u32, h + 1, sizeof u32); 1874 memcpy(&u32, h + 1, sizeof u32);
1874 if (ntohl(u32) == sp->lcp.magic) { 1875 if (ntohl(u32) == sp->lcp.magic) {
1875 /* Line loopback mode detected. */ 1876 /* Line loopback mode detected. */
1876 printf("%s: loopback\n", ifp->if_xname); 1877 printf("%s: loopback\n", ifp->if_xname);
1877 SPPP_UNLOCK(sp); 1878 SPPP_UNLOCK(sp);
1878 if_down(ifp); 1879 if_down(ifp);
1879 SPPP_LOCK(sp, RW_WRITER); 1880 SPPP_LOCK(sp, RW_WRITER);
1880 1881
1881 IF_PURGE(&sp->pp_cpq); 1882 IF_PURGE(&sp->pp_cpq);
1882 1883
1883 /* Shut down the PPP link. */ 1884 /* Shut down the PPP link. */
1884 /* XXX */ 1885 /* XXX */
1885 lcp.Down(sp); 1886 lcp.Down(sp);
1886 lcp.Up(sp); 1887 lcp.Up(sp);
1887 break; 1888 break;
1888 } 1889 }
1889 u32 = htonl(sp->lcp.magic); 1890 u32 = htonl(sp->lcp.magic);
1890 memcpy(h + 1, &u32, sizeof u32); 1891 memcpy(h + 1, &u32, sizeof u32);
1891 if (debug) 1892 if (debug)
1892 addlog("%s: got lcp echo req, sending echo rep\n", 1893 addlog("%s: got lcp echo req, sending echo rep\n",
1893 ifp->if_xname); 1894 ifp->if_xname);
1894 sppp_cp_send(sp, PPP_LCP, ECHO_REPLY, h->ident, len - 4, 1895 sppp_cp_send(sp, PPP_LCP, ECHO_REPLY, h->ident, len - 4,
1895 h + 1); 1896 h + 1);
1896 break; 1897 break;
1897 case ECHO_REPLY: 1898 case ECHO_REPLY:
1898 if (cp->proto != PPP_LCP) 1899 if (cp->proto != PPP_LCP)
1899 goto illegal; 1900 goto illegal;
1900 if (h->ident != sp->lcp.echoid) { 1901 if (h->ident != sp->lcp.echoid) {
1901 ++ifp->if_ierrors; 1902 ++ifp->if_ierrors;
1902 break; 1903 break;
1903 } 1904 }
1904 if (len < 8) { 1905 if (len < 8) {
1905 if (debug) 1906 if (debug)
1906 addlog("%s: lcp invalid echo reply " 1907 addlog("%s: lcp invalid echo reply "
1907 "packet length: %d bytes\n", 1908 "packet length: %d bytes\n",
1908 ifp->if_xname, len); 1909 ifp->if_xname, len);
1909 break; 1910 break;
1910 } 1911 }
1911 if (debug) 1912 if (debug)
1912 addlog("%s: lcp got echo rep\n", 1913 addlog("%s: lcp got echo rep\n",
1913 ifp->if_xname); 1914 ifp->if_xname);
1914 memcpy(&u32, h + 1, sizeof u32); 1915 memcpy(&u32, h + 1, sizeof u32);
1915 if (ntohl(u32) != sp->lcp.magic) 1916 if (ntohl(u32) != sp->lcp.magic)
1916 sp->pp_alivecnt = 0; 1917 sp->pp_alivecnt = 0;
1917 break; 1918 break;
1918 default: 1919 default:
1919 /* Unknown packet type -- send Code-Reject packet. */ 1920 /* Unknown packet type -- send Code-Reject packet. */
1920 illegal: 1921 illegal:
1921 if (debug) 1922 if (debug)
1922 addlog("%s: %s send code-rej for 0x%x\n", 1923 addlog("%s: %s send code-rej for 0x%x\n",
1923 ifp->if_xname, cp->name, h->type); 1924 ifp->if_xname, cp->name, h->type);
1924 sppp_cp_send(sp, cp->proto, CODE_REJ, 1925 sppp_cp_send(sp, cp->proto, CODE_REJ,
1925 ++sp->pp_seq[cp->protoidx], m->m_pkthdr.len, h); 1926 ++sp->pp_seq[cp->protoidx], m->m_pkthdr.len, h);
1926 ++ifp->if_ierrors; 1927 ++ifp->if_ierrors;
1927 } 1928 }
1928 1929
1929 SPPP_UNLOCK(sp); 1930 SPPP_UNLOCK(sp);
1930} 1931}
1931 1932
1932 1933
1933/* 1934/*
1934 * The generic part of all Up/Down/Open/Close/TO event handlers. 1935 * The generic part of all Up/Down/Open/Close/TO event handlers.
1935 * Basically, the state transition handling in the automaton. 1936 * Basically, the state transition handling in the automaton.
1936 */ 1937 */
1937static void 1938static void
1938sppp_up_event(const struct cp *cp, struct sppp *sp) 1939sppp_up_event(const struct cp *cp, struct sppp *sp)
1939{ 1940{
1940 STDDCL; 1941 STDDCL;
1941 1942
1942 KASSERT(SPPP_WLOCKED(sp)); 1943 KASSERT(SPPP_WLOCKED(sp));
1943 1944
1944 if (debug) 1945 if (debug)
1945 log(LOG_DEBUG, "%s: %s up(%s)\n", 1946 log(LOG_DEBUG, "%s: %s up(%s)\n",
1946 ifp->if_xname, cp->name, 1947 ifp->if_xname, cp->name,
1947 sppp_state_name(sp->state[cp->protoidx])); 1948 sppp_state_name(sp->state[cp->protoidx]));
1948 1949
1949 switch (sp->state[cp->protoidx]) { 1950 switch (sp->state[cp->protoidx]) {
1950 case STATE_INITIAL: 1951 case STATE_INITIAL:
1951 sppp_cp_change_state(cp, sp, STATE_CLOSED); 1952 sppp_cp_change_state(cp, sp, STATE_CLOSED);
1952 break; 1953 break;
1953 case STATE_STARTING: 1954 case STATE_STARTING:
1954 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 1955 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
1955 (cp->scr)(sp); 1956 (cp->scr)(sp);
1956 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 1957 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
1957 break; 1958 break;
1958 default: 1959 default:
1959 printf("%s: %s illegal up in state %s\n", 1960 printf("%s: %s illegal up in state %s\n",
1960 ifp->if_xname, cp->name, 1961 ifp->if_xname, cp->name,
1961 sppp_state_name(sp->state[cp->protoidx])); 1962 sppp_state_name(sp->state[cp->protoidx]));
1962 } 1963 }
1963} 1964}
1964 1965
1965static void 1966static void
1966sppp_down_event(const struct cp *cp, struct sppp *sp) 1967sppp_down_event(const struct cp *cp, struct sppp *sp)
1967{ 1968{
1968 STDDCL; 1969 STDDCL;
1969 1970
1970 KASSERT(SPPP_WLOCKED(sp)); 1971 KASSERT(SPPP_WLOCKED(sp));
1971 1972
1972 if (debug) 1973 if (debug)
1973 log(LOG_DEBUG, "%s: %s down(%s)\n", 1974 log(LOG_DEBUG, "%s: %s down(%s)\n",
1974 ifp->if_xname, cp->name, 1975 ifp->if_xname, cp->name,
1975 sppp_state_name(sp->state[cp->protoidx])); 1976 sppp_state_name(sp->state[cp->protoidx]));
1976 1977
1977 switch (sp->state[cp->protoidx]) { 1978 switch (sp->state[cp->protoidx]) {
1978 case STATE_CLOSED: 1979 case STATE_CLOSED:
1979 case STATE_CLOSING: 1980 case STATE_CLOSING:
1980 sppp_cp_change_state(cp, sp, STATE_INITIAL); 1981 sppp_cp_change_state(cp, sp, STATE_INITIAL);
1981 break; 1982 break;
1982 case STATE_STOPPED: 1983 case STATE_STOPPED:
1983 (cp->tls)(sp); 1984 (cp->tls)(sp);
1984 /* fall through */ 1985 /* fall through */
1985 case STATE_STOPPING: 1986 case STATE_STOPPING:
1986 case STATE_REQ_SENT: 1987 case STATE_REQ_SENT:
1987 case STATE_ACK_RCVD: 1988 case STATE_ACK_RCVD:
1988 case STATE_ACK_SENT: 1989 case STATE_ACK_SENT:
1989 sppp_cp_change_state(cp, sp, STATE_STARTING); 1990 sppp_cp_change_state(cp, sp, STATE_STARTING);
1990 break; 1991 break;
1991 case STATE_OPENED: 1992 case STATE_OPENED:
1992 (cp->tld)(sp); 1993 (cp->tld)(sp);
1993 sppp_cp_change_state(cp, sp, STATE_STARTING); 1994 sppp_cp_change_state(cp, sp, STATE_STARTING);
1994 break; 1995 break;
1995 default: 1996 default:
1996 printf("%s: %s illegal down in state %s\n", 1997 printf("%s: %s illegal down in state %s\n",
1997 ifp->if_xname, cp->name, 1998 ifp->if_xname, cp->name,
1998 sppp_state_name(sp->state[cp->protoidx])); 1999 sppp_state_name(sp->state[cp->protoidx]));
1999 } 2000 }
2000} 2001}
2001 2002
2002 2003
2003static void 2004static void
2004sppp_open_event(const struct cp *cp, struct sppp *sp) 2005sppp_open_event(const struct cp *cp, struct sppp *sp)
2005{ 2006{
2006 STDDCL; 2007 STDDCL;
2007 2008
2008 KASSERT(SPPP_WLOCKED(sp)); 2009 KASSERT(SPPP_WLOCKED(sp));
2009 2010
2010 if (debug) 2011 if (debug)
2011 log(LOG_DEBUG, "%s: %s open(%s)\n", 2012 log(LOG_DEBUG, "%s: %s open(%s)\n",
2012 ifp->if_xname, cp->name, 2013 ifp->if_xname, cp->name,
2013 sppp_state_name(sp->state[cp->protoidx])); 2014 sppp_state_name(sp->state[cp->protoidx]));
2014 2015
2015 switch (sp->state[cp->protoidx]) { 2016 switch (sp->state[cp->protoidx]) {
2016 case STATE_INITIAL: 2017 case STATE_INITIAL:
2017 sppp_cp_change_state(cp, sp, STATE_STARTING); 2018 sppp_cp_change_state(cp, sp, STATE_STARTING);
2018 (cp->tls)(sp); 2019 (cp->tls)(sp);
2019 break; 2020 break;
2020 case STATE_STARTING: 2021 case STATE_STARTING:
2021 break; 2022 break;
2022 case STATE_CLOSED: 2023 case STATE_CLOSED:
2023 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure; 2024 sp->rst_counter[cp->protoidx] = sp->lcp.max_configure;
2024 (cp->scr)(sp); 2025 (cp->scr)(sp);
2025 sppp_cp_change_state(cp, sp, STATE_REQ_SENT); 2026 sppp_cp_change_state(cp, sp, STATE_REQ_SENT);
2026 break; 2027 break;
2027 case STATE_STOPPED: 2028 case STATE_STOPPED:
2028 case STATE_STOPPING: 2029 case STATE_STOPPING:
2029 case STATE_REQ_SENT: 2030 case STATE_REQ_SENT:
2030 case STATE_ACK_RCVD: 2031 case STATE_ACK_RCVD:
2031 case STATE_ACK_SENT: 2032 case STATE_ACK_SENT:
2032 case STATE_OPENED: 2033 case STATE_OPENED:
2033 break; 2034 break;
2034 case STATE_CLOSING: 2035 case STATE_CLOSING:
2035 sppp_cp_change_state(cp, sp, STATE_STOPPING); 2036 sppp_cp_change_state(cp, sp, STATE_STOPPING);
2036 break; 2037 break;
2037 } 2038 }
2038} 2039}
2039 2040
2040 2041
2041static void 2042static void
2042sppp_close_event(const struct cp *cp, struct sppp *sp) 2043sppp_close_event(const struct cp *cp, struct sppp *sp)
2043{ 2044{
2044 STDDCL; 2045 STDDCL;
2045 2046
2046 KASSERT(SPPP_WLOCKED(sp)); 2047 KASSERT(SPPP_WLOCKED(sp));
2047 2048
2048 if (debug) 2049 if (debug)
2049 log(LOG_DEBUG, "%s: %s close(%s)\n", 2050 log(LOG_DEBUG, "%s: %s close(%s)\n",
2050 ifp->if_xname, cp->name, 2051 ifp->if_xname, cp->name,
2051 sppp_state_name(sp->state[cp->protoidx])); 2052 sppp_state_name(sp->state[cp->protoidx]));
2052 2053
2053 switch (sp->state[cp->protoidx]) { 2054 switch (sp->state[cp->protoidx]) {
2054 case STATE_INITIAL: 2055 case STATE_INITIAL:
2055 case STATE_CLOSED: 2056 case STATE_CLOSED:
2056 case STATE_CLOSING: 2057 case STATE_CLOSING:
2057 break; 2058 break;
2058 case STATE_STARTING: 2059 case STATE_STARTING:
2059 sppp_cp_change_state(cp, sp, STATE_INITIAL); 2060 sppp_cp_change_state(cp, sp, STATE_INITIAL);
2060 (cp->tlf)(sp); 2061 (cp->tlf)(sp);
2061 break; 2062 break;
2062 case STATE_STOPPED: 2063 case STATE_STOPPED:
2063 sppp_cp_change_state(cp, sp, STATE_CLOSED); 2064 sppp_cp_change_state(cp, sp, STATE_CLOSED);
2064 break; 2065 break;
2065 case STATE_STOPPING: 2066 case STATE_STOPPING:
2066 sppp_cp_change_state(cp, sp, STATE_CLOSING); 2067 sppp_cp_change_state(cp, sp, STATE_CLOSING);
2067 break; 2068 break;
2068 case STATE_OPENED: 2069 case STATE_OPENED:
2069 (cp->tld)(sp); 2070 (cp->tld)(sp);
2070 /* fall through */ 2071 /* fall through */
2071 case STATE_REQ_SENT: 2072 case STATE_REQ_SENT:
2072 case STATE_ACK_RCVD: 2073 case STATE_ACK_RCVD:
2073 case STATE_ACK_SENT: 2074 case STATE_ACK_SENT:
2074 sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate; 2075 sp->rst_counter[cp->protoidx] = sp->lcp.max_terminate;