Révision b6a7bd2f
Ajouté par Ermal il y a presque 10 ans
patches/stable/10/stf_6rd.diff | ||
---|---|---|
12 | 12 |
DPADD+= ${LIBBSDXML} ${LIBSBUF} |
13 | 13 |
diff --git a/sbin/ifconfig/ifstf.c b/sbin/ifconfig/ifstf.c |
14 | 14 |
new file mode 100644 |
15 |
index 0000000..8c8b3fb
|
|
15 |
index 0000000..df532cb
|
|
16 | 16 |
--- /dev/null |
17 | 17 |
+++ b/sbin/ifconfig/ifstf.c |
18 |
@@ -0,0 +1,156 @@
|
|
18 |
@@ -0,0 +1,155 @@
|
|
19 | 19 |
+/*- |
20 | 20 |
+ * Copyright 2013 Ermal Luci |
21 | 21 |
+ * All rights reserved. |
... | ... | |
91 | 91 |
+ if (do_cmd(s, STF_GV4NET, ¶m, sizeof(param), 0) < 0) |
92 | 92 |
+ return; |
93 | 93 |
+ |
94 |
+ printf("\tv4net %s/%d\n", inet_ntoa(param.inaddr), param.prefix); |
|
95 |
+ printf("\tv4br %s\n", inet_ntoa(param.dstv4_addr)); |
|
94 |
+ printf("\tv4net %s/%d -> tv4br %s\n", inet_ntoa(param.inaddr), param.prefix, inet_ntoa(param.dstv4_addr)); |
|
96 | 95 |
+ |
97 | 96 |
+ return; |
98 | 97 |
+} |
... | ... | |
173 | 172 |
+#undef N |
174 | 173 |
+} |
175 | 174 |
diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c |
176 |
index 20251dc..3d56b2d 100644
|
|
175 |
index 20251dc..5652ee6 100644
|
|
177 | 176 |
--- a/sys/net/if_stf.c |
178 | 177 |
+++ b/sys/net/if_stf.c |
179 | 178 |
@@ -3,6 +3,8 @@ |
... | ... | |
294 | 293 |
#define IN6_IS_ADDR_6TO4(x) (ntohs((x)->s6_addr16[0]) == 0x2002) |
295 | 294 |
|
296 | 295 |
/* |
297 |
@@ -149,19 +187,31 @@ struct stf_softc { |
|
296 |
@@ -144,24 +182,37 @@ SYSCTL_INT(_net_link_stf, OID_AUTO, permit_rfc1918, CTLFLAG_RW | CTLFLAG_TUN, |
|
297 |
|
|
298 |
struct stf_softc { |
|
299 |
struct ifnet *sc_ifp; |
|
300 |
+ in_addr_t dstv4_addr; |
|
301 |
+ in_addr_t srcv4_addr; |
|
302 |
+ in_addr_t inaddr; |
|
303 |
+ u_int v4prefixlen; |
|
304 |
union { |
|
305 |
struct route __sc_ro4; |
|
298 | 306 |
struct route_in6 __sc_ro6; /* just for safety */ |
299 | 307 |
} __sc_ro46; |
300 | 308 |
#define sc_ro __sc_ro46.__sc_ro4 |
... | ... | |
303 | 311 |
u_int sc_fibnum; |
304 | 312 |
const struct encaptab *encap_cookie; |
305 | 313 |
+ u_int sc_flags; |
306 |
+ u_int v4prefixlen; |
|
307 |
+ in_addr_t inaddr; |
|
308 |
+ in_addr_t dstv4_addr; |
|
309 | 314 |
+ LIST_ENTRY(stf_softc) stf_list; |
310 | 315 |
}; |
311 | 316 |
#define STF2IFP(sc) ((sc)->sc_ifp) |
... | ... | |
331 | 336 |
static const int ip_stf_ttl = 40; |
332 | 337 |
|
333 | 338 |
extern struct domain inetdomain; |
334 |
@@ -176,8 +226,6 @@ struct protosw in_stf_protosw = {
|
|
339 |
@@ -176,8 +227,6 @@ struct protosw in_stf_protosw = {
|
|
335 | 340 |
.pr_usrreqs = &rip_usrreqs |
336 | 341 |
}; |
337 | 342 |
|
... | ... | |
340 | 345 |
static int stfmodevent(module_t, int, void *); |
341 | 346 |
static int stf_encapcheck(const struct mbuf *, int, int, void *); |
342 | 347 |
static struct in6_ifaddr *stf_getsrcifa6(struct ifnet *); |
343 |
@@ -191,66 +239,42 @@ static int stf_checkaddr6(struct stf_softc *, struct in6_addr *,
|
|
348 |
@@ -191,66 +240,42 @@ static int stf_checkaddr6(struct stf_softc *, struct in6_addr *,
|
|
344 | 349 |
static void stf_rtrequest(int, struct rtentry *, struct rt_addrinfo *); |
345 | 350 |
static int stf_ioctl(struct ifnet *, u_long, caddr_t); |
346 | 351 |
|
... | ... | |
424 | 429 |
return (ENOMEM); |
425 | 430 |
} |
426 | 431 |
|
427 |
@@ -260,42 +284,56 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
|
432 |
@@ -260,42 +285,56 @@ stf_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
|
428 | 433 |
ifp->if_snd.ifq_maxlen = ifqmaxlen; |
429 | 434 |
if_attach(ifp); |
430 | 435 |
bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); |
... | ... | |
492 | 497 |
break; |
493 | 498 |
default: |
494 | 499 |
return (EOPNOTSUPP); |
495 |
@@ -311,28 +349,31 @@ static moduledata_t stf_mod = {
|
|
500 |
@@ -311,28 +350,31 @@ static moduledata_t stf_mod = {
|
|
496 | 501 |
}; |
497 | 502 |
|
498 | 503 |
DECLARE_MODULE(if_stf, stf_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); |
... | ... | |
532 | 537 |
return 0; |
533 | 538 |
|
534 | 539 |
if (proto != IPPROTO_IPV6) |
535 |
@@ -344,72 +385,156 @@ stf_encapcheck(m, off, proto, arg)
|
|
540 |
@@ -344,72 +386,157 @@ stf_encapcheck(m, off, proto, arg)
|
|
536 | 541 |
if (ip.ip_v != 4) |
537 | 542 |
return 0; |
538 | 543 |
|
... | ... | |
599 | 604 |
- if (a.s_addr != b.s_addr) |
600 | 605 |
- return 0; |
601 | 606 |
+ DEBUG_PRINTF(1, "%s: check2: ia6->ia_addr is 2002::/16?\n", __func__); |
607 |
+ |
|
602 | 608 |
+ if (IN6_IS_ADDR_6TO4(&ia6->ia_addr.sin6_addr)) { |
603 | 609 |
+ /* 6to4 (RFC 3056) */ |
604 | 610 |
+ /* |
... | ... | |
725 | 731 |
} |
726 | 732 |
|
727 | 733 |
static int |
728 |
@@ -419,8 +544,8 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
734 |
@@ -419,8 +546,8 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
729 | 735 |
struct stf_softc *sc; |
730 | 736 |
const struct sockaddr_in6 *dst6; |
731 | 737 |
struct route *cached_route; |
... | ... | |
736 | 742 |
struct sockaddr_in *dst4; |
737 | 743 |
u_int8_t tos; |
738 | 744 |
struct ip *ip; |
739 |
@@ -472,20 +597,32 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
745 |
@@ -472,20 +599,32 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
740 | 746 |
/* |
741 | 747 |
* Pickup the right outer dst addr from the list of candidates. |
742 | 748 |
* ip6_dst has priority as it may be able to give us shorter IPv4 hops. |
... | ... | |
779 | 785 |
if (bpf_peers_present(ifp->if_bpf)) { |
780 | 786 |
/* |
781 | 787 |
* We need to prepend the address family as |
782 |
@@ -509,11 +646,26 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
788 |
@@ -509,11 +648,30 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
783 | 789 |
ip = mtod(m, struct ip *); |
784 | 790 |
|
785 | 791 |
bzero(ip, sizeof(*ip)); |
... | ... | |
787 | 793 |
|
788 | 794 |
- bcopy(GET_V4(&((struct sockaddr_in6 *)&ia6->ia_addr)->sin6_addr), |
789 | 795 |
- &ip->ip_src, sizeof(ip->ip_src)); |
790 |
+ sin = stf_getin4addr_sin6(sc, &in4, &ia6->ia_ifa, &ia6->ia_addr); |
|
791 |
+ if (sin == NULL) { |
|
792 |
+ ifa_free(&ia6->ia_ifa); |
|
793 |
+ m_freem(m); |
|
794 |
+ ifp->if_oerrors++; |
|
795 |
+ return ENETUNREACH; |
|
796 |
+ if (sc->srcv4_addr != INADDR_ANY) |
|
797 |
+ in4.sin_addr.s_addr = sc->srcv4_addr; |
|
798 |
+ else { |
|
799 |
+ sin = stf_getin4addr_sin6(sc, &in4, &ia6->ia_ifa, &ia6->ia_addr); |
|
800 |
+ if (sin == NULL) { |
|
801 |
+ ifa_free(&ia6->ia_ifa); |
|
802 |
+ m_freem(m); |
|
803 |
+ ifp->if_oerrors++; |
|
804 |
+ return ENETUNREACH; |
|
805 |
+ } |
|
796 | 806 |
+ } |
797 | 807 |
+ bcopy(&in4.sin_addr, &ip->ip_src, sizeof(ip->ip_src)); |
798 | 808 |
+#if STF_DEBUG > 3 |
... | ... | |
809 | 819 |
ip->ip_p = IPPROTO_IPV6; |
810 | 820 |
ip->ip_ttl = ip_stf_ttl; |
811 | 821 |
ip->ip_len = htons(m->m_pkthdr.len); |
812 |
@@ -522,7 +674,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
822 |
@@ -522,7 +680,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
813 | 823 |
else |
814 | 824 |
ip_ecn_ingress(ECN_NOCARE, &ip->ip_tos, &tos); |
815 | 825 |
|
... | ... | |
818 | 828 |
cached_route = NULL; |
819 | 829 |
goto sendit; |
820 | 830 |
} |
821 |
@@ -530,7 +682,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
831 |
@@ -530,7 +688,7 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
822 | 832 |
/* |
823 | 833 |
* Do we have a cached route? |
824 | 834 |
*/ |
... | ... | |
827 | 837 |
dst4 = (struct sockaddr_in *)&sc->sc_ro.ro_dst; |
828 | 838 |
if (dst4->sin_family != AF_INET || |
829 | 839 |
bcmp(&dst4->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)) != 0) { |
830 |
@@ -548,8 +700,15 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
840 |
@@ -548,8 +706,15 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
831 | 841 |
rtalloc_fib(&sc->sc_ro, sc->sc_fibnum); |
832 | 842 |
if (sc->sc_ro.ro_rt == NULL) { |
833 | 843 |
m_freem(m); |
... | ... | |
844 | 854 |
return ENETUNREACH; |
845 | 855 |
} |
846 | 856 |
} |
847 |
@@ -558,35 +717,33 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
857 |
@@ -558,35 +723,33 @@ stf_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
|
|
848 | 858 |
sendit: |
849 | 859 |
M_SETFIB(m, sc->sc_fibnum); |
850 | 860 |
ifp->if_opackets++; |
... | ... | |
889 | 899 |
{ |
890 | 900 |
struct in_ifaddr *ia4; |
891 | 901 |
|
892 |
@@ -602,13 +759,6 @@ stf_checkaddr4(sc, in, inifp)
|
|
902 |
@@ -602,13 +765,6 @@ stf_checkaddr4(sc, in, inifp)
|
|
893 | 903 |
} |
894 | 904 |
|
895 | 905 |
/* |
... | ... | |
903 | 913 |
* reject packets with broadcast |
904 | 914 |
*/ |
905 | 915 |
IN_IFADDR_RLOCK(); |
906 |
@@ -631,7 +781,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
916 |
@@ -631,7 +787,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
907 | 917 |
|
908 | 918 |
bzero(&sin, sizeof(sin)); |
909 | 919 |
sin.sin_family = AF_INET; |
... | ... | |
912 | 922 |
sin.sin_addr = *in; |
913 | 923 |
rt = rtalloc1_fib((struct sockaddr *)&sin, 0, |
914 | 924 |
0UL, sc->sc_fibnum); |
915 |
@@ -652,10 +802,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
925 |
@@ -652,10 +808,7 @@ stf_checkaddr4(sc, in, inifp)
|
|
916 | 926 |
} |
917 | 927 |
|
918 | 928 |
static int |
... | ... | |
924 | 934 |
{ |
925 | 935 |
/* |
926 | 936 |
* check 6to4 addresses |
927 |
@@ -679,9 +826,7 @@ stf_checkaddr6(sc, in6, inifp)
|
|
937 |
@@ -679,9 +832,7 @@ stf_checkaddr6(sc, in6, inifp)
|
|
928 | 938 |
} |
929 | 939 |
|
930 | 940 |
void |
... | ... | |
935 | 945 |
{ |
936 | 946 |
int proto; |
937 | 947 |
struct stf_softc *sc; |
938 |
@@ -689,6 +834,7 @@ in_stf_input(m, off)
|
|
948 |
@@ -689,6 +840,7 @@ in_stf_input(m, off)
|
|
939 | 949 |
struct ip6_hdr *ip6; |
940 | 950 |
u_int8_t otos, itos; |
941 | 951 |
struct ifnet *ifp; |
... | ... | |
943 | 953 |
|
944 | 954 |
proto = mtod(m, struct ip *)->ip_p; |
945 | 955 |
|
946 |
@@ -712,6 +858,17 @@ in_stf_input(m, off)
|
|
956 |
@@ -712,6 +864,17 @@ in_stf_input(m, off)
|
|
947 | 957 |
mac_ifnet_create_mbuf(ifp, m); |
948 | 958 |
#endif |
949 | 959 |
|
... | ... | |
961 | 971 |
/* |
962 | 972 |
* perform sanity check against outer src/dst. |
963 | 973 |
* for source, perform ingress filter as well. |
964 |
@@ -732,6 +889,17 @@ in_stf_input(m, off)
|
|
974 |
@@ -732,6 +895,17 @@ in_stf_input(m, off)
|
|
965 | 975 |
} |
966 | 976 |
ip6 = mtod(m, struct ip6_hdr *); |
967 | 977 |
|
... | ... | |
979 | 989 |
/* |
980 | 990 |
* perform sanity check against inner src/dst. |
981 | 991 |
* for source, perform ingress filter as well. |
982 |
@@ -742,6 +910,41 @@ in_stf_input(m, off)
|
|
992 |
@@ -742,6 +916,41 @@ in_stf_input(m, off)
|
|
983 | 993 |
return; |
984 | 994 |
} |
985 | 995 |
|
... | ... | |
1021 | 1031 |
itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff; |
1022 | 1032 |
if ((ifp->if_flags & IFF_LINK1) != 0) |
1023 | 1033 |
ip_ecn_egress(ECN_ALLOWED, &otos, &itos); |
1024 |
@@ -751,7 +954,7 @@ in_stf_input(m, off)
|
|
1034 |
@@ -751,7 +960,7 @@ in_stf_input(m, off)
|
|
1025 | 1035 |
ip6->ip6_flow |= htonl((u_int32_t)itos << 20); |
1026 | 1036 |
|
1027 | 1037 |
m->m_pkthdr.rcvif = ifp; |
... | ... | |
1030 | 1040 |
if (bpf_peers_present(ifp->if_bpf)) { |
1031 | 1041 |
/* |
1032 | 1042 |
* We need to prepend the address family as |
1033 |
@@ -764,6 +967,7 @@ in_stf_input(m, off)
|
|
1043 |
@@ -764,6 +973,7 @@ in_stf_input(m, off)
|
|
1034 | 1044 |
bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m); |
1035 | 1045 |
} |
1036 | 1046 |
|
... | ... | |
1038 | 1048 |
/* |
1039 | 1049 |
* Put the packet to the network layer input queue according to the |
1040 | 1050 |
* specified address family. |
1041 |
@@ -778,46 +982,356 @@ in_stf_input(m, off)
|
|
1051 |
@@ -778,46 +988,355 @@ in_stf_input(m, off)
|
|
1042 | 1052 |
|
1043 | 1053 |
/* ARGSUSED */ |
1044 | 1054 |
static void |
... | ... | |
1228 | 1238 |
+ DEBUG_PRINTF(2, "residue = %d\n", residue); |
1229 | 1239 |
+ for (i = loop; i >= 0; i--) { |
1230 | 1240 |
+ if (residue) { |
1231 |
+ DEBUG_PRINTF(2, "p[%d] << residue = %d-%x/%x\n", |
|
1232 |
+ i, p[i], p[i], p[i] >> residue); |
|
1233 |
+ p[i] = (p[i] >> residue); |
|
1234 |
+ DEBUG_PRINTF(2, "p[%d] = %d/%x - p[%d 1] = %d-%x/%x\n", |
|
1235 |
+ i, p[i], p[i], i, p[i - 1], p[i - 1], p[i - 1] << (8 - residue)); |
|
1236 |
+ p[i] |= (p[i - 1] << (8 - residue)); |
|
1237 |
+ } |
|
1238 |
+ q[i - 1] = p[i]; |
|
1241 |
+ q[i] |= (p[i] & mask) | (p[i - 1] >> (8 - residue)); |
|
1242 |
+ } else |
|
1243 |
+ q[i - 1] = p[i]; |
|
1239 | 1244 |
+ DEBUG_PRINTF(2, "FINAL q[%d] - p[%d] %d/%x\n", |
1240 | 1245 |
+ i, i, q[i - 1], q[i]); |
1241 | 1246 |
+ } |
1242 | 1247 |
+ if (v4residue) |
1243 |
+ q[i + 1] &= v4mask;
|
|
1248 |
+ q[i + 1] &= v4mask;
|
|
1244 | 1249 |
+ |
1245 | 1250 |
+ if (sc->v4prefixlen) |
1246 |
+ in->s_addr |= (sc->inaddr & ((uint32_t)(-1) >> sc->v4prefixlen)); |
|
1251 |
+ in->s_addr |= sc->inaddr; |
|
1252 |
+ |
|
1253 |
+ if (in->s_addr != sc->srcv4_addr) |
|
1254 |
+ printf("Wrong decoded address!!!!\n"); |
|
1247 | 1255 |
+ } |
1248 | 1256 |
+ |
1249 | 1257 |
+#if STF_DEBUG > 3 |
... | ... | |
1263 | 1271 |
+ DEBUG_PRINTF(1, "%s: try to memset 0 to ia_dstaddr.\n", __func__); |
1264 | 1272 |
+ memset(&ia6->ia_dstaddr, 0, sizeof(ia6->ia_dstaddr)); |
1265 | 1273 |
+ DEBUG_PRINTF(1, "%s: try to memcpy ifa->ifa_dstaddr.\n", __func__); |
1266 |
+ memcpy((struct sockaddr_in *)ifa->ifa_dstaddr,
|
|
1274 |
+ memcpy((struct sockaddr_in *)ifa->ifa_dstaddr, |
|
1267 | 1275 |
+ sin, sizeof(struct sockaddr_in)); |
1268 | 1276 |
+ DEBUG_PRINTF(1, "%s: try to set sa_family.\n", __func__); |
1269 | 1277 |
+ ifa->ifa_dstaddr->sa_family = AF_INET; |
... | ... | |
1331 | 1339 |
+ if (error) |
1332 | 1340 |
+ break; |
1333 | 1341 |
+ |
1342 |
+ sc_cur->srcv4_addr = args.inaddr.s_addr; |
|
1334 | 1343 |
+ sc_cur->inaddr = ntohl(args.inaddr.s_addr); |
1335 | 1344 |
+ sc_cur->inaddr &= ((uint32_t)(-1) << args.prefix); |
1336 | 1345 |
+ sc_cur->inaddr = htonl(sc_cur->inaddr); |
... | ... | |
1361 | 1370 |
+ break; |
1362 | 1371 |
+ } |
1363 | 1372 |
+ bzero(&args, sizeof args); |
1364 |
+ args.inaddr.s_addr = sc_cur->inaddr;
|
|
1373 |
+ args.inaddr.s_addr = sc_cur->srcv4_addr;
|
|
1365 | 1374 |
+ args.dstv4_addr.s_addr = sc_cur->dstv4_addr; |
1366 | 1375 |
+ args.prefix = sc_cur->v4prefixlen; |
1367 | 1376 |
+ error = copyout(&args, ifd->ifd_data, ifd->ifd_len); |
... | ... | |
1412 | 1421 |
ifa->ifa_rtrequest = stf_rtrequest; |
1413 | 1422 |
ifp->if_flags |= IFF_UP; |
1414 | 1423 |
break; |
1415 |
@@ -849,4 +1363,5 @@ stf_ioctl(ifp, cmd, data)
|
|
1424 |
@@ -849,4 +1368,5 @@ stf_ioctl(ifp, cmd, data)
|
|
1416 | 1425 |
} |
1417 | 1426 |
|
1418 | 1427 |
return error; |
Formats disponibles : Unified diff
First try at correcting 6rd