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); |