Révision f41bc703
Ajouté par Ermal il y a presque 10 ans
patches/stable/10/stf_6rd.diff | ||
---|---|---|
173 | 173 |
+#undef N |
174 | 174 |
+} |
175 | 175 |
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c |
176 |
index 20251dc..532750b 100644
|
|
176 |
index 20251dc..3d56b2d 100644
|
|
177 | 177 |
--- a/sys/net/if_stf.c |
178 | 178 |
+++ b/sys/net/if_stf.c |
179 | 179 |
@@ -3,6 +3,8 @@ |
... | ... | |
340 | 340 |
static int stfmodevent(module_t, int, void *); |
341 | 341 |
static int stf_encapcheck(const struct mbuf *, int, int, void *); |
342 | 342 |
static struct in6_ifaddr *stf_getsrcifa6(struct ifnet *); |
343 |
@@ -191,66 +239,66 @@ static int stf_checkaddr6(struct stf_softc *, struct in6_addr *,
|
|
343 |
@@ -191,66 +239,42 @@ static int stf_checkaddr6(struct stf_softc *, struct in6_addr *,
|
|
344 | 344 |
static void stf_rtrequest(int, struct rtentry *, struct rt_addrinfo *); |
345 | 345 |
static int stf_ioctl(struct ifnet *, u_long, caddr_t); |
346 | 346 |
|
347 | 347 |
-static int stf_clone_match(struct if_clone *, const char *); |
348 |
-static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t); |
|
349 |
-static int stf_clone_destroy(struct if_clone *, struct ifnet *); |
|
350 |
-static struct if_clone *stf_cloner; |
|
348 | 351 |
+#define STF_GETIN4_USE_CACHE 1 |
349 | 352 |
+static struct sockaddr_in *stf_getin4addr(struct stf_softc *, struct sockaddr_in *, |
350 | 353 |
+ struct ifaddr *, int); |
... | ... | |
352 | 355 |
+ struct ifaddr *, const struct in6_addr *); |
353 | 356 |
+static struct sockaddr_in *stf_getin4addr_sin6(struct stf_softc *, struct sockaddr_in *, |
354 | 357 |
+ struct ifaddr *, struct sockaddr_in6 *); |
355 |
static int stf_clone_create(struct if_clone *, char *, size_t, caddr_t); |
|
356 |
static int stf_clone_destroy(struct if_clone *, struct ifnet *); |
|
357 |
+static int stf_clone_match(struct if_clone *, const char *); |
|
358 |
+ |
|
359 |
static struct if_clone *stf_cloner; |
|
358 |
+static int stf_clone_create(struct if_clone *, int, caddr_t); |
|
359 |
+static void stf_clone_destroy(struct ifnet *); |
|
360 | 360 |
|
361 |
static int
|
|
362 |
stf_clone_match(struct if_clone *ifc, const char *name)
|
|
363 |
{
|
|
361 |
-static int
|
|
362 |
-stf_clone_match(struct if_clone *ifc, const char *name)
|
|
363 |
-{
|
|
364 | 364 |
- int i; |
365 |
+ const char *cp; |
|
366 |
|
|
365 |
- |
|
367 | 366 |
- for(i = 0; stfnames[i] != NULL; i++) { |
368 | 367 |
- if (strcmp(stfnames[i], name) == 0) |
369 | 368 |
- return (1); |
370 | 369 |
- } |
371 |
+ if (strncmp(stfname, name, strlen(stfname)) != 0) |
|
372 |
+ return (0); |
|
373 |
|
|
370 |
- |
|
374 | 371 |
- return (0); |
375 |
+ for (cp = name + 3; *cp != '\0'; cp++) { |
|
376 |
+ if (*cp < '0' || *cp > '9') |
|
377 |
+ return (0); |
|
378 |
+ } |
|
379 |
+ return (1); |
|
380 |
} |
|
372 |
-} |
|
373 |
+static struct if_clone *stf_cloner; |
|
381 | 374 |
|
382 | 375 |
static int |
383 |
stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) |
|
376 |
-stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) |
|
377 |
+stf_clone_create(struct if_clone *ifc, int unit, caddr_t params) |
|
384 | 378 |
{ |
385 | 379 |
- int err, unit; |
386 | 380 |
struct stf_softc *sc; |
387 | 381 |
struct ifnet *ifp; |
388 |
+ int unit, error; |
|
389 | 382 |
|
390 | 383 |
- /* |
391 | 384 |
- * We can only have one unit, but since unit allocation is |
... | ... | |
396 | 389 |
- err = ifc_alloc_unit(ifc, &unit); |
397 | 390 |
- if (err != 0) |
398 | 391 |
- return (err); |
399 |
+ error = ifc_name2unit(name, &unit); |
|
400 |
+ if (error != 0) |
|
401 |
+ return (error); |
|
402 |
+ |
|
403 |
+ error = ifc_alloc_unit(ifc, &unit); |
|
404 |
+ if (error != 0) |
|
405 |
+ return (error); |
|
406 |
|
|
392 |
- |
|
407 | 393 |
sc = malloc(sizeof(struct stf_softc), M_STF, M_WAITOK | M_ZERO); |
408 | 394 |
+ sc->sc_fibnum = curthread->td_proc->p_fibnum; |
409 | 395 |
ifp = STF2IFP(sc) = if_alloc(IFT_STF); |
... | ... | |
425 | 411 |
- strlcpy(ifp->if_xname, name, IFNAMSIZ); |
426 | 412 |
- ifp->if_dname = stfname; |
427 | 413 |
- ifp->if_dunit = IF_DUNIT_NONE; |
428 |
+ if_initname(ifp, name, unit); |
|
414 |
+ if_initname(ifp, stfname, unit);
|
|
429 | 415 |
|
430 | 416 |
- mtx_init(&(sc)->sc_ro_mtx, "stf ro", NULL, MTX_DEF); |
431 | 417 |
sc->encap_cookie = encap_attach_func(AF_INET, IPPROTO_IPV6, |
432 | 418 |
stf_encapcheck, &in_stf_protosw, sc); |
433 | 419 |
if (sc->encap_cookie == NULL) { |
434 | 420 |
if_printf(ifp, "attach failed\n"); |
421 |
+ if_free(ifp); |
|
435 | 422 |
free(sc, M_STF); |
436 | 423 |
- ifc_free_unit(ifc, unit); |
437 | 424 |
return (ENOMEM); |
438 | 425 |
} |
439 | 426 |
|
440 |
@@ -260,6 +308,11 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
|
427 |
@@ -260,42 +284,56 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
|
441 | 428 |
ifp->if_snd.ifq_maxlen = ifqmaxlen; |
442 | 429 |
if_attach(ifp); |
443 | 430 |
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); |
... | ... | |
449 | 436 |
return (0); |
450 | 437 |
} |
451 | 438 |
|
452 |
@@ -267,35 +320,48 @@ static int |
|
453 |
stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) |
|
439 |
-static int |
|
440 |
-stf_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) |
|
441 |
+static void |
|
442 |
+stf_clone_destroy(struct ifnet *ifp) |
|
454 | 443 |
{ |
455 | 444 |
struct stf_softc *sc = ifp->if_softc; |
456 |
+ int unit = ifp->if_dunit; |
|
457 | 445 |
int err; |
458 | 446 |
|
459 | 447 |
+ mtx_lock(&stf_mtx); |
... | ... | |
470 | 458 |
+ STF_LOCK_DESTROY(sc); |
471 | 459 |
free(sc, M_STF); |
472 | 460 |
- ifc_free_unit(ifc, STFUNIT); |
473 |
+ ifc_free_unit(ifc, unit); |
|
474 |
|
|
475 |
return (0); |
|
476 |
} |
|
461 |
+} |
|
477 | 462 |
|
463 |
- return (0); |
|
478 | 464 |
+static void |
479 | 465 |
+vnet_stf_init(const void *unused __unused) |
480 | 466 |
+{ |
481 | 467 |
+ |
482 | 468 |
+ LIST_INIT(&V_stf_softc_list); |
483 |
+}
|
|
469 |
}
|
|
484 | 470 |
+VNET_SYSINIT(vnet_stf_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, vnet_stf_init, |
485 | 471 |
+ NULL); |
486 |
+ |
|
472 |
|
|
487 | 473 |
static int |
488 | 474 |
-stfmodevent(mod, type, data) |
489 | 475 |
- module_t mod; |
... | ... | |
494 | 480 |
|
495 | 481 |
switch (type) { |
496 | 482 |
case MOD_LOAD: |
483 |
- stf_cloner = if_clone_advanced(stfname, 0, stf_clone_match, |
|
484 |
- stf_clone_create, stf_clone_destroy); |
|
497 | 485 |
+ mtx_init(&stf_mtx, "stf_mtx", NULL, MTX_DEF); |
498 |
stf_cloner = if_clone_advanced(stfname, 0, stf_clone_match,
|
|
499 |
stf_clone_create, stf_clone_destroy);
|
|
486 |
+ stf_cloner = if_clone_simple(stfname,
|
|
487 |
+ stf_clone_create, stf_clone_destroy, 0);
|
|
500 | 488 |
break; |
501 | 489 |
case MOD_UNLOAD: |
502 | 490 |
if_clone_detach(stf_cloner); |
... | ... | |
504 | 492 |
break; |
505 | 493 |
default: |
506 | 494 |
return (EOPNOTSUPP); |
507 |
@@ -311,28 +377,31 @@ static moduledata_t stf_mod = {
|
|
495 |
@@ -311,28 +349,31 @@ static moduledata_t stf_mod = {
|
|
508 | 496 |
}; |
509 | 497 |
|
510 | 498 |
DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); |
... | ... | |
544 | 532 |
return 0; |
545 | 533 |
|
546 | 534 |
if (proto != IPPROTO_IPV6) |
547 |
@@ -344,72 +413,156 @@ stf_encapcheck(m, off, proto, arg)
|
|
535 |
@@ -344,72 +385,156 @@ stf_encapcheck(m, off, proto, arg)
|
|
548 | 536 |
if (ip.ip_v != 4) |
549 | 537 |
return 0; |
550 | 538 |
|
... | ... | |
737 | 725 |
} |
738 | 726 |
|
739 | 727 |
static int |
740 |
@@ -419,8 +572,8 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
728 |
@@ -419,8 +544,8 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
741 | 729 |
struct stf_softc *sc; |
742 | 730 |
const struct sockaddr_in6 *dst6; |
743 | 731 |
struct route *cached_route; |
... | ... | |
748 | 736 |
struct sockaddr_in *dst4; |
749 | 737 |
u_int8_t tos; |
750 | 738 |
struct ip *ip; |
751 |
@@ -472,20 +625,32 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
739 |
@@ -472,20 +597,32 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
752 | 740 |
/* |
753 | 741 |
* Pickup the right outer dst addr from the list of candidates. |
754 | 742 |
* ip6_dst has priority as it may be able to give us shorter IPv4 hops. |
... | ... | |
791 | 779 |
if (bpf_peers_present(ifp->if_bpf)) { |
792 | 780 |
/* |
793 | 781 |
* We need to prepend the address family as |
794 |
@@ -509,11 +674,26 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
782 |
@@ -509,11 +646,26 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
795 | 783 |
ip = mtod(m, struct ip *); |
796 | 784 |
|
797 | 785 |
bzero(ip, sizeof(*ip)); |
... | ... | |
821 | 809 |
ip->ip_p = IPPROTO_IPV6; |
822 | 810 |
ip->ip_ttl = ip_stf_ttl; |
823 | 811 |
ip->ip_len = htons(m->m_pkthdr.len); |
824 |
@@ -522,7 +702,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
812 |
@@ -522,7 +674,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
825 | 813 |
else |
826 | 814 |
ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); |
827 | 815 |
|
... | ... | |
830 | 818 |
cached_route = NULL; |
831 | 819 |
goto sendit; |
832 | 820 |
} |
833 |
@@ -530,7 +710,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
821 |
@@ -530,7 +682,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
834 | 822 |
/* |
835 | 823 |
* Do we have a cached route? |
836 | 824 |
*/ |
... | ... | |
839 | 827 |
dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; |
840 | 828 |
if (dst4->sin_family != AF_INET || |
841 | 829 |
bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) { |
842 |
@@ -548,8 +728,15 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
830 |
@@ -548,8 +700,15 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
843 | 831 |
rtalloc_fib(&sc->sc_ro, sc->sc_fibnum); |
844 | 832 |
if (sc->sc_ro.ro_rt == NULL) { |
845 | 833 |
m_freem(m); |
... | ... | |
856 | 844 |
return ENETUNREACH; |
857 | 845 |
} |
858 | 846 |
} |
859 |
@@ -558,35 +745,33 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
847 |
@@ -558,35 +717,33 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
860 | 848 |
sendit: |
861 | 849 |
M_SETFIB(m, sc->sc_fibnum); |
862 | 850 |
ifp->if_opackets++; |
... | ... | |
901 | 889 |
{ |
902 | 890 |
struct in_ifaddr *ia4; |
903 | 891 |
|
904 |
@@ -602,13 +787,6 @@ stf_checkaddr4(sc, in, inifp)
|
|
892 |
@@ -602,13 +759,6 @@ stf_checkaddr4(sc, in, inifp)
|
|
905 | 893 |
} |
906 | 894 |
|
907 | 895 |
/* |
... | ... | |
915 | 903 |
* reject packets with broadcast |
916 | 904 |
*/ |
917 | 905 |
IN_IFADDR_RLOCK(); |
918 |
@@ -631,7 +809,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
906 |
@@ -631,7 +781,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
919 | 907 |
|
920 | 908 |
bzero(&sin, sizeof(sin)); |
921 | 909 |
sin.sin_family = AF_INET; |
... | ... | |
924 | 912 |
sin.sin_addr = *in; |
925 | 913 |
rt = rtalloc1_fib((struct sockaddr *)&sin, 0, |
926 | 914 |
0UL, sc->sc_fibnum); |
927 |
@@ -652,10 +830,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
915 |
@@ -652,10 +802,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
928 | 916 |
} |
929 | 917 |
|
930 | 918 |
static int |
... | ... | |
936 | 924 |
{ |
937 | 925 |
/* |
938 | 926 |
* check 6to4 addresses |
939 |
@@ -679,9 +854,7 @@ stf_checkaddr6(sc, in6, inifp)
|
|
927 |
@@ -679,9 +826,7 @@ stf_checkaddr6(sc, in6, inifp)
|
|
940 | 928 |
} |
941 | 929 |
|
942 | 930 |
void |
... | ... | |
947 | 935 |
{ |
948 | 936 |
int proto; |
949 | 937 |
struct stf_softc *sc; |
950 |
@@ -689,6 +862,7 @@ in_stf_input(m, off)
|
|
938 |
@@ -689,6 +834,7 @@ in_stf_input(m, off)
|
|
951 | 939 |
struct ip6_hdr *ip6; |
952 | 940 |
u_int8_t otos, itos; |
953 | 941 |
struct ifnet *ifp; |
... | ... | |
955 | 943 |
|
956 | 944 |
proto = mtod(m, struct ip *)->ip_p; |
957 | 945 |
|
958 |
@@ -712,6 +886,17 @@ in_stf_input(m, off)
|
|
946 |
@@ -712,6 +858,17 @@ in_stf_input(m, off)
|
|
959 | 947 |
mac_ifnet_create_mbuf(ifp, m); |
960 | 948 |
#endif |
961 | 949 |
|
... | ... | |
973 | 961 |
/* |
974 | 962 |
* perform sanity check against outer src/dst. |
975 | 963 |
* for source, perform ingress filter as well. |
976 |
@@ -732,6 +917,17 @@ in_stf_input(m, off)
|
|
964 |
@@ -732,6 +889,17 @@ in_stf_input(m, off)
|
|
977 | 965 |
} |
978 | 966 |
ip6 = mtod(m, struct ip6_hdr *); |
979 | 967 |
|
... | ... | |
991 | 979 |
/* |
992 | 980 |
* perform sanity check against inner src/dst. |
993 | 981 |
* for source, perform ingress filter as well. |
994 |
@@ -742,6 +938,41 @@ in_stf_input(m, off)
|
|
982 |
@@ -742,6 +910,41 @@ in_stf_input(m, off)
|
|
995 | 983 |
return; |
996 | 984 |
} |
997 | 985 |
|
... | ... | |
1033 | 1021 |
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; |
1034 | 1022 |
if ((ifp->if_flags & IFF_LINK1) != 0) |
1035 | 1023 |
ip_ecn_egress(ECN_ALLOWED, &otos, &itos); |
1036 |
@@ -751,7 +982,7 @@ in_stf_input(m, off)
|
|
1024 |
@@ -751,7 +954,7 @@ in_stf_input(m, off)
|
|
1037 | 1025 |
ip6->ip6_flow |= htonl((u_int32_t)itos << 20); |
1038 | 1026 |
|
1039 | 1027 |
m->m_pkthdr.rcvif = ifp; |
... | ... | |
1042 | 1030 |
if (bpf_peers_present(ifp->if_bpf)) { |
1043 | 1031 |
/* |
1044 | 1032 |
* We need to prepend the address family as |
1045 |
@@ -764,6 +995,7 @@ in_stf_input(m, off)
|
|
1033 |
@@ -764,6 +967,7 @@ in_stf_input(m, off)
|
|
1046 | 1034 |
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m); |
1047 | 1035 |
} |
1048 | 1036 |
|
... | ... | |
1050 | 1038 |
/* |
1051 | 1039 |
* Put the packet to the network layer input queue according to the |
1052 | 1040 |
* specified address family. |
1053 |
@@ -778,46 +1010,356 @@ in_stf_input(m, off)
|
|
1041 |
@@ -778,46 +982,356 @@ in_stf_input(m, off)
|
|
1054 | 1042 |
|
1055 | 1043 |
/* ARGSUSED */ |
1056 | 1044 |
static void |
... | ... | |
1424 | 1412 |
ifa->ifa_rtrequest = stf_rtrequest; |
1425 | 1413 |
ifp->if_flags |= IFF_UP; |
1426 | 1414 |
break; |
1427 |
@@ -849,4 +1391,5 @@ stf_ioctl(ifp, cmd, data)
|
|
1415 |
@@ -849,4 +1363,5 @@ stf_ioctl(ifp, cmd, data)
|
|
1428 | 1416 |
} |
1429 | 1417 |
|
1430 | 1418 |
return error; |
Formats disponibles : Unified diff
Correct issues with stf panics reported