Deleted Added
full compact
if_gre.c (271867) if_gre.c (271918)
1/* $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $ */
1/* $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $ */
2/* $FreeBSD: head/sys/net/if_gre.c 271867 2014-09-19 10:39:58Z glebius $ */
2/* $FreeBSD: head/sys/net/if_gre.c 271918 2014-09-21 03:56:06Z hrs $ */
3
4/*-
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Heiko W.Rupp <hwr@pilhuhn.de>
10 *

--- 86 unchanged lines hidden (view full) ---

97 uint16_t max;
98 struct ifnet *ifp[];
99};
100
101/*
102 * gre_mtx protects all global variables in if_gre.c.
103 * XXX: gre_softc data not protected yet.
104 */
3
4/*-
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Heiko W.Rupp <hwr@pilhuhn.de>
10 *

--- 86 unchanged lines hidden (view full) ---

97 uint16_t max;
98 struct ifnet *ifp[];
99};
100
101/*
102 * gre_mtx protects all global variables in if_gre.c.
103 * XXX: gre_softc data not protected yet.
104 */
105struct mtx gre_mtx;
105VNET_DEFINE(struct mtx, gre_mtx);
106VNET_DEFINE(struct gre_softc_head, gre_softc_list);
107
106static const char grename[] = "gre";
107static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
108
108static const char grename[] = "gre";
109static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
110
109struct gre_softc_head gre_softc_list;
110
111static int gre_clone_create(struct if_clone *, int, caddr_t);
112static void gre_clone_destroy(struct ifnet *);
111static int gre_clone_create(struct if_clone *, int, caddr_t);
112static void gre_clone_destroy(struct ifnet *);
113static struct if_clone *gre_cloner;
113static VNET_DEFINE(struct if_clone *, gre_cloner);
114#define V_gre_cloner VNET(gre_cloner)
114
115static int gre_ioctl(struct ifnet *, u_long, caddr_t);
116static int gre_output(struct ifnet *, struct mbuf *,
117 const struct sockaddr *, struct route *);
118
119static int gre_compute_route(struct gre_softc *sc);
120
115
116static int gre_ioctl(struct ifnet *, u_long, caddr_t);
117static int gre_output(struct ifnet *, struct mbuf *,
118 const struct sockaddr *, struct route *);
119
120static int gre_compute_route(struct gre_softc *sc);
121
121static void greattach(void);
122
123#ifdef INET
124extern struct domain inetdomain;
125static const struct protosw in_gre_protosw = {
126 .pr_type = SOCK_RAW,
127 .pr_domain = &inetdomain,
128 .pr_protocol = IPPROTO_GRE,
129 .pr_flags = PR_ATOMIC|PR_ADDR,
130 .pr_input = gre_input,

--- 24 unchanged lines hidden (view full) ---

155 * Since, setting a large value to this macro with a careless configuration
156 * may introduce system crash, we don't allow any nestings by default.
157 * If you need to configure nested gre tunnels, you can define this macro
158 * in your kernel configuration file. However, if you do so, please be
159 * careful to configure the tunnels so that it won't make a loop.
160 */
161#define MAX_GRE_NEST 1
162#endif
122#ifdef INET
123extern struct domain inetdomain;
124static const struct protosw in_gre_protosw = {
125 .pr_type = SOCK_RAW,
126 .pr_domain = &inetdomain,
127 .pr_protocol = IPPROTO_GRE,
128 .pr_flags = PR_ATOMIC|PR_ADDR,
129 .pr_input = gre_input,

--- 24 unchanged lines hidden (view full) ---

154 * Since, setting a large value to this macro with a careless configuration
155 * may introduce system crash, we don't allow any nestings by default.
156 * If you need to configure nested gre tunnels, you can define this macro
157 * in your kernel configuration file. However, if you do so, please be
158 * careful to configure the tunnels so that it won't make a loop.
159 */
160#define MAX_GRE_NEST 1
161#endif
163static int max_gre_nesting = MAX_GRE_NEST;
164SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW,
165 &max_gre_nesting, 0, "Max nested tunnels");
162static VNET_DEFINE(int, max_gre_nesting) = MAX_GRE_NEST;
163#define V_max_gre_nesting VNET(max_gre_nesting)
164SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET,
165 &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels");
166
166
167/* ARGSUSED */
168static void
167static void
169greattach(void)
168vnet_gre_init(const void *unused __unused)
170{
169{
171
172 mtx_init(&gre_mtx, "gre_mtx", NULL, MTX_DEF);
173 LIST_INIT(&gre_softc_list);
174 gre_cloner = if_clone_simple(grename, gre_clone_create,
170 LIST_INIT(&V_gre_softc_list);
171 GRE_LIST_LOCK_INIT();
172 V_gre_cloner = if_clone_simple(grename, gre_clone_create,
175 gre_clone_destroy, 0);
176}
173 gre_clone_destroy, 0);
174}
175VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
176 vnet_gre_init, NULL);
177
177
178static void
179vnet_gre_uninit(const void *unused __unused)
180{
181
182 if_clone_detach(V_gre_cloner);
183 GRE_LIST_LOCK_DESTROY();
184}
185VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
186 vnet_gre_uninit, NULL);
187
178static int
188static int
179gre_clone_create(ifc, unit, params)
180 struct if_clone *ifc;
181 int unit;
182 caddr_t params;
189gre_clone_create(struct if_clone *ifc, int unit, caddr_t params)
183{
184 struct gre_softc *sc;
185
186 sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
187
188 GRE2IFP(sc) = if_alloc(IFT_TUNNEL);
189 if (GRE2IFP(sc) == NULL) {
190 free(sc, M_GRE);

--- 14 unchanged lines hidden (view full) ---

205 sc->g_proto = IPPROTO_GRE;
206 GRE2IFP(sc)->if_flags |= IFF_LINK0;
207 sc->encap = NULL;
208 sc->gre_fibnum = curthread->td_proc->p_fibnum;
209 sc->wccp_ver = WCCP_V1;
210 sc->key = 0;
211 if_attach(GRE2IFP(sc));
212 bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
190{
191 struct gre_softc *sc;
192
193 sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
194
195 GRE2IFP(sc) = if_alloc(IFT_TUNNEL);
196 if (GRE2IFP(sc) == NULL) {
197 free(sc, M_GRE);

--- 14 unchanged lines hidden (view full) ---

212 sc->g_proto = IPPROTO_GRE;
213 GRE2IFP(sc)->if_flags |= IFF_LINK0;
214 sc->encap = NULL;
215 sc->gre_fibnum = curthread->td_proc->p_fibnum;
216 sc->wccp_ver = WCCP_V1;
217 sc->key = 0;
218 if_attach(GRE2IFP(sc));
219 bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
213 mtx_lock(&gre_mtx);
214 LIST_INSERT_HEAD(&gre_softc_list, sc, sc_list);
215 mtx_unlock(&gre_mtx);
220 GRE_LIST_LOCK();
221 LIST_INSERT_HEAD(&V_gre_softc_list, sc, sc_list);
222 GRE_LIST_UNLOCK();
216 return (0);
217}
218
219static void
223 return (0);
224}
225
226static void
220gre_clone_destroy(ifp)
221 struct ifnet *ifp;
227gre_clone_destroy(struct ifnet *ifp)
222{
223 struct gre_softc *sc = ifp->if_softc;
224
228{
229 struct gre_softc *sc = ifp->if_softc;
230
225 mtx_lock(&gre_mtx);
231 GRE_LIST_LOCK();
226 LIST_REMOVE(sc, sc_list);
232 LIST_REMOVE(sc, sc_list);
227 mtx_unlock(&gre_mtx);
233 GRE_LIST_UNLOCK();
228
229#ifdef INET
230 if (sc->encap != NULL)
231 encap_detach(sc->encap);
232#endif
233 bpfdetach(ifp);
234 if_detach(ifp);
235 if_free(ifp);

--- 28 unchanged lines hidden (view full) ---

264 * detecting loops and by introducing upper limit.
265 */
266 mtag = m_tag_locate(m, MTAG_COOKIE_GRE, MTAG_GRE_NESTING, NULL);
267 if (mtag != NULL) {
268 struct ifnet **ifp2;
269
270 gt = (struct mtag_gre_nesting *)(mtag + 1);
271 gt->count++;
234
235#ifdef INET
236 if (sc->encap != NULL)
237 encap_detach(sc->encap);
238#endif
239 bpfdetach(ifp);
240 if_detach(ifp);
241 if_free(ifp);

--- 28 unchanged lines hidden (view full) ---

270 * detecting loops and by introducing upper limit.
271 */
272 mtag = m_tag_locate(m, MTAG_COOKIE_GRE, MTAG_GRE_NESTING, NULL);
273 if (mtag != NULL) {
274 struct ifnet **ifp2;
275
276 gt = (struct mtag_gre_nesting *)(mtag + 1);
277 gt->count++;
272 if (gt->count > min(gt->max,max_gre_nesting)) {
278 if (gt->count > min(gt->max, V_max_gre_nesting)) {
273 printf("%s: hit maximum recursion limit %u on %s\n",
274 __func__, gt->count - 1, ifp->if_xname);
275 m_freem(m);
276 error = EIO; /* is there better errno? */
277 goto end;
278 }
279
280 ifp2 = gt->ifp;

--- 15 unchanged lines hidden (view full) ---

296 /*
297 * Given that people should NOT increase max_gre_nesting beyond
298 * their real needs, we allocate once per packet rather than
299 * allocating an mtag once per passing through gre.
300 *
301 * Note: the sysctl does not actually check for saneness, so we
302 * limit the maximum numbers of possible recursions here.
303 */
279 printf("%s: hit maximum recursion limit %u on %s\n",
280 __func__, gt->count - 1, ifp->if_xname);
281 m_freem(m);
282 error = EIO; /* is there better errno? */
283 goto end;
284 }
285
286 ifp2 = gt->ifp;

--- 15 unchanged lines hidden (view full) ---

302 /*
303 * Given that people should NOT increase max_gre_nesting beyond
304 * their real needs, we allocate once per packet rather than
305 * allocating an mtag once per passing through gre.
306 *
307 * Note: the sysctl does not actually check for saneness, so we
308 * limit the maximum numbers of possible recursions here.
309 */
304 max = imin(max_gre_nesting, 256);
310 max = imin(V_max_gre_nesting, 256);
305 /* If someone sets the sysctl <= 0, we want at least 1. */
306 max = imax(max, 1);
307 len = sizeof(struct mtag_gre_nesting) +
308 max * sizeof(struct ifnet *);
309 mtag = m_tag_alloc(MTAG_COOKIE_GRE, MTAG_GRE_NESTING, len,
310 M_NOWAIT);
311 if (mtag == NULL) {
312 m_freem(m);

--- 591 unchanged lines hidden (view full) ---

904}
905
906static int
907gremodevent(module_t mod, int type, void *data)
908{
909
910 switch (type) {
911 case MOD_LOAD:
311 /* If someone sets the sysctl <= 0, we want at least 1. */
312 max = imax(max, 1);
313 len = sizeof(struct mtag_gre_nesting) +
314 max * sizeof(struct ifnet *);
315 mtag = m_tag_alloc(MTAG_COOKIE_GRE, MTAG_GRE_NESTING, len,
316 M_NOWAIT);
317 if (mtag == NULL) {
318 m_freem(m);

--- 591 unchanged lines hidden (view full) ---

910}
911
912static int
913gremodevent(module_t mod, int type, void *data)
914{
915
916 switch (type) {
917 case MOD_LOAD:
912 greattach();
913 break;
914 case MOD_UNLOAD:
918 case MOD_UNLOAD:
915 if_clone_detach(gre_cloner);
916 mtx_destroy(&gre_mtx);
917 break;
918 default:
919 break;
920 default:
919 return EOPNOTSUPP;
921 return (EOPNOTSUPP);
920 }
922 }
921 return 0;
923 return (0);
922}
923
924static moduledata_t gre_mod = {
925 "if_gre",
926 gremodevent,
927 0
928};
929
930DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
931MODULE_VERSION(if_gre, 1);
924}
925
926static moduledata_t gre_mod = {
927 "if_gre",
928 gremodevent,
929 0
930};
931
932DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
933MODULE_VERSION(if_gre, 1);