Projet

Général

Profil

« Précédent | Suivant » 

Révision f41bc703

Ajouté par Ermal il y a presque 10 ans

Correct issues with stf panics reported

Voir les différences:

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