if_gif.c (271867) | if_gif.c (271917) |
---|---|
1/* $FreeBSD: head/sys/net/if_gif.c 271867 2014-09-19 10:39:58Z glebius $ */ | 1/* $FreeBSD: head/sys/net/if_gif.c 271917 2014-09-21 03:55:04Z hrs $ */ |
2/* $KAME: if_gif.c,v 1.87 2001/10/19 08:50:27 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 77 unchanged lines hidden (view full) --- 87#include <net/if_bridgevar.h> 88#include <net/if_gif.h> 89 90#include <security/mac/mac_framework.h> 91 92static const char gifname[] = "gif"; 93 94/* | 2/* $KAME: if_gif.c,v 1.87 2001/10/19 08:50:27 itojun Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 77 unchanged lines hidden (view full) --- 87#include <net/if_bridgevar.h> 88#include <net/if_gif.h> 89 90#include <security/mac/mac_framework.h> 91 92static const char gifname[] = "gif"; 93 94/* |
95 * gif_mtx protects the global gif_softc_list. | 95 * gif_mtx protects a per-vnet gif_softc_list. |
96 */ | 96 */ |
97static struct mtx gif_mtx; | 97static VNET_DEFINE(struct mtx, gif_mtx); 98#define V_gif_mtx VNET(gif_mtx) |
98static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); 99static VNET_DEFINE(LIST_HEAD(, gif_softc), gif_softc_list); 100#define V_gif_softc_list VNET(gif_softc_list) 101 | 99static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); 100static VNET_DEFINE(LIST_HEAD(, gif_softc), gif_softc_list); 101#define V_gif_softc_list VNET(gif_softc_list) 102 |
103#define GIF_LIST_LOCK_INIT(x) mtx_init(&V_gif_mtx, "gif_mtx", \ 104 NULL, MTX_DEF) 105#define GIF_LIST_LOCK_DESTROY(x) mtx_destroy(&V_gif_mtx) 106#define GIF_LIST_LOCK(x) mtx_lock(&V_gif_mtx) 107#define GIF_LIST_UNLOCK(x) mtx_unlock(&V_gif_mtx) 108 |
|
102void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af); 103void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af); 104void (*ng_gif_attach_p)(struct ifnet *ifp); 105void (*ng_gif_detach_p)(struct ifnet *ifp); 106 107static void gif_start(struct ifnet *); 108static int gif_clone_create(struct if_clone *, int, caddr_t); 109static void gif_clone_destroy(struct ifnet *); | 109void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af); 110void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af); 111void (*ng_gif_attach_p)(struct ifnet *ifp); 112void (*ng_gif_detach_p)(struct ifnet *ifp); 113 114static void gif_start(struct ifnet *); 115static int gif_clone_create(struct if_clone *, int, caddr_t); 116static void gif_clone_destroy(struct ifnet *); |
110static struct if_clone *gif_cloner; | 117static VNET_DEFINE(struct if_clone *, gif_cloner); 118#define V_gif_cloner VNET(gif_cloner) |
111 112static int gifmodevent(module_t, int, void *); 113 114SYSCTL_DECL(_net_link); 115static SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0, 116 "Generic Tunnel Interface"); 117#ifndef MAX_GIF_NEST 118/* --- 65 unchanged lines hidden (view full) --- 184 GIF2IFP(sc)->if_start = gif_start; 185 GIF2IFP(sc)->if_output = gif_output; 186 GIF2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen; 187 if_attach(GIF2IFP(sc)); 188 bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int32_t)); 189 if (ng_gif_attach_p != NULL) 190 (*ng_gif_attach_p)(GIF2IFP(sc)); 191 | 119 120static int gifmodevent(module_t, int, void *); 121 122SYSCTL_DECL(_net_link); 123static SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0, 124 "Generic Tunnel Interface"); 125#ifndef MAX_GIF_NEST 126/* --- 65 unchanged lines hidden (view full) --- 192 GIF2IFP(sc)->if_start = gif_start; 193 GIF2IFP(sc)->if_output = gif_output; 194 GIF2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen; 195 if_attach(GIF2IFP(sc)); 196 bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int32_t)); 197 if (ng_gif_attach_p != NULL) 198 (*ng_gif_attach_p)(GIF2IFP(sc)); 199 |
192 mtx_lock(&gif_mtx); | 200 GIF_LIST_LOCK(); |
193 LIST_INSERT_HEAD(&V_gif_softc_list, sc, gif_list); | 201 LIST_INSERT_HEAD(&V_gif_softc_list, sc, gif_list); |
194 mtx_unlock(&gif_mtx); | 202 GIF_LIST_UNLOCK(); |
195 196 return (0); 197} 198 199static void 200gif_clone_destroy(struct ifnet *ifp) 201{ 202#if defined(INET) || defined(INET6) 203 int err; 204#endif 205 struct gif_softc *sc = ifp->if_softc; 206 | 203 204 return (0); 205} 206 207static void 208gif_clone_destroy(struct ifnet *ifp) 209{ 210#if defined(INET) || defined(INET6) 211 int err; 212#endif 213 struct gif_softc *sc = ifp->if_softc; 214 |
207 mtx_lock(&gif_mtx); | 215 GIF_LIST_LOCK(); |
208 LIST_REMOVE(sc, gif_list); | 216 LIST_REMOVE(sc, gif_list); |
209 mtx_unlock(&gif_mtx); | 217 GIF_LIST_UNLOCK(); |
210 211 gif_delete_tunnel(ifp); 212#ifdef INET6 213 if (sc->encap_cookie6 != NULL) { 214 err = encap_detach(sc->encap_cookie6); 215 KASSERT(err == 0, ("Unexpected error detaching encap_cookie6")); 216 } 217#endif --- 15 unchanged lines hidden (view full) --- 233 free(sc, M_GIF); 234} 235 236static void 237vnet_gif_init(const void *unused __unused) 238{ 239 240 LIST_INIT(&V_gif_softc_list); | 218 219 gif_delete_tunnel(ifp); 220#ifdef INET6 221 if (sc->encap_cookie6 != NULL) { 222 err = encap_detach(sc->encap_cookie6); 223 KASSERT(err == 0, ("Unexpected error detaching encap_cookie6")); 224 } 225#endif --- 15 unchanged lines hidden (view full) --- 241 free(sc, M_GIF); 242} 243 244static void 245vnet_gif_init(const void *unused __unused) 246{ 247 248 LIST_INIT(&V_gif_softc_list); |
249 GIF_LIST_LOCK_INIT(); 250 V_gif_cloner = if_clone_simple(gifname, gif_clone_create, 251 gif_clone_destroy, 0); |
|
241} | 252} |
242VNET_SYSINIT(vnet_gif_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, vnet_gif_init, 243 NULL); | 253VNET_SYSINIT(vnet_gif_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 254 vnet_gif_init, NULL); |
244 | 255 |
256static void 257vnet_gif_uninit(const void *unused __unused) 258{ 259 260 if_clone_detach(V_gif_cloner); 261 GIF_LIST_LOCK_DESTROY(); 262} 263VNET_SYSUNINIT(vnet_gif_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 264 vnet_gif_uninit, NULL); 265 |
|
245static int 246gifmodevent(module_t mod, int type, void *data) 247{ 248 249 switch (type) { 250 case MOD_LOAD: | 266static int 267gifmodevent(module_t mod, int type, void *data) 268{ 269 270 switch (type) { 271 case MOD_LOAD: |
251 mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF); 252 gif_cloner = if_clone_simple(gifname, gif_clone_create, 253 gif_clone_destroy, 0); 254 break; 255 | |
256 case MOD_UNLOAD: | 272 case MOD_UNLOAD: |
257 if_clone_detach(gif_cloner); 258 mtx_destroy(&gif_mtx); | |
259 break; 260 default: | 273 break; 274 default: |
261 return EOPNOTSUPP; | 275 return (EOPNOTSUPP); |
262 } | 276 } |
263 return 0; | 277 return (0); |
264} 265 266static moduledata_t gif_mod = { 267 "if_gif", 268 gifmodevent, 269 0 270}; 271 --- 87 unchanged lines hidden (view full) --- 359#ifdef ALTQ 360 /* Take out those altq bytes we add in gif_output */ 361#ifdef INET 362 if (sc->gif_psrc->sa_family == AF_INET) 363 m->m_pkthdr.len -= GIF_HDR_LEN; 364#endif 365#ifdef INET6 366 if (sc->gif_psrc->sa_family == AF_INET6) | 278} 279 280static moduledata_t gif_mod = { 281 "if_gif", 282 gifmodevent, 283 0 284}; 285 --- 87 unchanged lines hidden (view full) --- 373#ifdef ALTQ 374 /* Take out those altq bytes we add in gif_output */ 375#ifdef INET 376 if (sc->gif_psrc->sa_family == AF_INET) 377 m->m_pkthdr.len -= GIF_HDR_LEN; 378#endif 379#ifdef INET6 380 if (sc->gif_psrc->sa_family == AF_INET6) |
367 m->m_pkthdr.len -= GIF_HDR_LEN6; | 381 m->m_pkthdr.len -= GIF_HDR_LEN6; |
368#endif 369#endif 370 /* 371 * Now pull back the af that we 372 * stashed in the csum_data. 373 */ 374 af = m->m_pkthdr.csum_data; 375 | 382#endif 383#endif 384 /* 385 * Now pull back the af that we 386 * stashed in the csum_data. 387 */ 388 af = m->m_pkthdr.csum_data; 389 |
390 /* override to IPPROTO_ETHERIP for bridged traffic */ |
|
376 if (ifp->if_bridge) 377 af = AF_LINK; 378 379 BPF_MTAP2(ifp, &af, sizeof(af), m); 380 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 381 382/* Done by IFQ_HANDOFF */ 383/* if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);*/ | 391 if (ifp->if_bridge) 392 af = AF_LINK; 393 394 BPF_MTAP2(ifp, &af, sizeof(af), m); 395 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 396 397/* Done by IFQ_HANDOFF */ 398/* if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);*/ |
384 /* override to IPPROTO_ETHERIP for bridged traffic */ | |
385 386 M_SETFIB(m, sc->gif_fibnum); 387 /* inner AF-specific encapsulation */ 388 /* XXX should we check if our outer source is legal? */ 389 /* dispatch to output logic based on outer AF */ 390 switch (sc->gif_psrc->sa_family) { 391#ifdef INET 392 case AF_INET: --- 506 unchanged lines hidden (view full) --- 899int 900gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) 901{ 902 struct gif_softc *sc = ifp->if_softc; 903 struct gif_softc *sc2; 904 struct sockaddr *osrc, *odst, *sa; 905 int error = 0; 906 | 399 400 M_SETFIB(m, sc->gif_fibnum); 401 /* inner AF-specific encapsulation */ 402 /* XXX should we check if our outer source is legal? */ 403 /* dispatch to output logic based on outer AF */ 404 switch (sc->gif_psrc->sa_family) { 405#ifdef INET 406 case AF_INET: --- 506 unchanged lines hidden (view full) --- 913int 914gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) 915{ 916 struct gif_softc *sc = ifp->if_softc; 917 struct gif_softc *sc2; 918 struct sockaddr *osrc, *odst, *sa; 919 int error = 0; 920 |
907 mtx_lock(&gif_mtx); | 921 GIF_LIST_LOCK(); |
908 LIST_FOREACH(sc2, &V_gif_softc_list, gif_list) { 909 if (sc2 == sc) 910 continue; 911 if (!sc2->gif_pdst || !sc2->gif_psrc) 912 continue; 913 if (sc2->gif_pdst->sa_family != dst->sa_family || 914 sc2->gif_pdst->sa_len != dst->sa_len || 915 sc2->gif_psrc->sa_family != src->sa_family || 916 sc2->gif_psrc->sa_len != src->sa_len) 917 continue; 918 919 /* 920 * Disallow parallel tunnels unless instructed 921 * otherwise. 922 */ 923 if (!V_parallel_tunnels && 924 bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 && 925 bcmp(sc2->gif_psrc, src, src->sa_len) == 0) { 926 error = EADDRNOTAVAIL; | 922 LIST_FOREACH(sc2, &V_gif_softc_list, gif_list) { 923 if (sc2 == sc) 924 continue; 925 if (!sc2->gif_pdst || !sc2->gif_psrc) 926 continue; 927 if (sc2->gif_pdst->sa_family != dst->sa_family || 928 sc2->gif_pdst->sa_len != dst->sa_len || 929 sc2->gif_psrc->sa_family != src->sa_family || 930 sc2->gif_psrc->sa_len != src->sa_len) 931 continue; 932 933 /* 934 * Disallow parallel tunnels unless instructed 935 * otherwise. 936 */ 937 if (!V_parallel_tunnels && 938 bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 && 939 bcmp(sc2->gif_psrc, src, src->sa_len) == 0) { 940 error = EADDRNOTAVAIL; |
927 mtx_unlock(&gif_mtx); | 941 GIF_LIST_UNLOCK(); |
928 goto bad; 929 } 930 931 /* XXX both end must be valid? (I mean, not 0.0.0.0) */ 932 } | 942 goto bad; 943 } 944 945 /* XXX both end must be valid? (I mean, not 0.0.0.0) */ 946 } |
933 mtx_unlock(&gif_mtx); | 947 GIF_LIST_UNLOCK(); |
934 935 /* XXX we can detach from both, but be polite just in case */ 936 if (sc->gif_psrc) 937 switch (sc->gif_psrc->sa_family) { 938#ifdef INET 939 case AF_INET: 940 (void)in_gif_detach(sc); 941 break; --- 85 unchanged lines hidden --- | 948 949 /* XXX we can detach from both, but be polite just in case */ 950 if (sc->gif_psrc) 951 switch (sc->gif_psrc->sa_family) { 952#ifdef INET 953 case AF_INET: 954 (void)in_gif_detach(sc); 955 break; --- 85 unchanged lines hidden --- |