Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109372777
D40102.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D40102.diff
View Options
diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c
--- a/sbin/ifconfig/ifpfsync.c
+++ b/sbin/ifconfig/ifpfsync.c
@@ -227,12 +227,17 @@
case AF_INET: {
struct sockaddr_in *sin = satosin(peerres->ai_addr);
- if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
- errx(1, "syncpeer address cannot be multicast");
-
memcpy(&addr, sin, sizeof(*sin));
break;
}
+#endif
+#ifdef INET6
+ case AF_INET6: {
+ struct sockaddr_in6 *sin6 = satosin6(peerres->ai_addr);
+
+ memcpy(&addr, sin6, sizeof(*sin6));
+ break;
+ }
#endif
default:
errx(1, "syncpeer address %s not supported", val);
@@ -377,9 +382,9 @@
if (syncdev[0] != '\0')
printf("syncdev: %s ", syncdev);
- if (syncpeer.ss_family == AF_INET &&
+ if ((syncpeer.ss_family == AF_INET &&
((struct sockaddr_in *)&syncpeer)->sin_addr.s_addr !=
- htonl(INADDR_PFSYNC_GROUP)) {
+ htonl(INADDR_PFSYNC_GROUP)) || syncpeer.ss_family == AF_INET6) {
struct sockaddr *syncpeer_sa =
(struct sockaddr *)&syncpeer;
diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c
--- a/sys/netpfil/pf/if_pfsync.c
+++ b/sys/netpfil/pf/if_pfsync.c
@@ -91,12 +91,15 @@
#include <net/if_types.h>
#include <net/vnet.h>
#include <net/pfvar.h>
+#include <net/route.h>
#include <net/if_pfsync.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
+#include <netinet6/in6_var.h>
#include <netinet/ip.h>
+#include <netinet/ip6.h>
#include <netinet/ip_carp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
@@ -105,6 +108,7 @@
#include <netinet/ip6.h>
#include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
#include <netpfil/pf/pfsync_nv.h>
@@ -112,7 +116,8 @@
struct pfsync_softc;
union inet_template {
- struct ip ipv4;
+ struct ip ipv4;
+ struct ip6_hdr ipv6;
};
#define PFSYNC_MINPKT ( \
@@ -247,6 +252,7 @@
struct ifnet *sc_ifp;
struct ifnet *sc_sync_if;
struct ip_moptions sc_imo;
+ struct ip6_moptions sc_im6o;
struct sockaddr_storage sc_sync_peer;
uint32_t sc_flags;
uint8_t sc_maxupdates;
@@ -303,7 +309,7 @@
static void pfsync_push_all(struct pfsync_softc *);
static void pfsyncintr(void *);
static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *,
- struct in_mfilter *imf);
+ struct in_mfilter *, struct in6_mfilter *);
static void pfsync_multicast_cleanup(struct pfsync_softc *);
static void pfsync_pointers_init(void);
static void pfsync_pointers_uninit(void);
@@ -368,6 +374,9 @@
VNET_DEFINE(struct if_clone *, pfsync_cloner);
#define V_pfsync_cloner VNET(pfsync_cloner)
+const struct in6_addr in6addr_linklocal_pfsync_group =
+ {{{ 0xff, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 }}};
static int
pfsync_clone_create(struct if_clone *ifc, int unit, caddr_t param)
{
@@ -842,6 +851,109 @@
}
#endif
+#ifdef INET6
+static int
+pfsync6_input(struct mbuf **mp, int *offp __unused, int proto __unused)
+{
+ struct pfsync_softc *sc = V_pfsyncif;
+ struct mbuf *m = *mp;
+ struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
+ struct pfsync_header *ph;
+ struct pfsync_subheader subh;
+
+ int offset, len, flags = 0;
+ int rv;
+ uint16_t count;
+
+ PF_RULES_RLOCK_TRACKER;
+
+ *mp = NULL;
+ V_pfsyncstats.pfsyncs_ipackets++;
+
+ /* Verify that we have a sync interface configured. */
+ if (!sc || !sc->sc_sync_if || !V_pf_status.running ||
+ (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ goto done;
+
+ /* verify that the packet came in on the right interface */
+ if (sc->sc_sync_if != m->m_pkthdr.rcvif) {
+ V_pfsyncstats.pfsyncs_badif++;
+ goto done;
+ }
+
+ if_inc_counter(sc->sc_ifp, IFCOUNTER_IPACKETS, 1);
+ if_inc_counter(sc->sc_ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
+ /* verify that the IP TTL is 255. */
+ if (ip6->ip6_hlim != PFSYNC_DFLTTL) {
+ V_pfsyncstats.pfsyncs_badttl++;
+ goto done;
+ }
+
+
+ offset = sizeof(*ip6);
+ if (m->m_pkthdr.len < offset + sizeof(*ph)) {
+ V_pfsyncstats.pfsyncs_hdrops++;
+ goto done;
+ }
+
+ if (offset + sizeof(*ph) > m->m_len) {
+ if (m_pullup(m, offset + sizeof(*ph)) == NULL) {
+ V_pfsyncstats.pfsyncs_hdrops++;
+ return (IPPROTO_DONE);
+ }
+ ip6 = mtod(m, struct ip6_hdr *);
+ }
+ ph = (struct pfsync_header *)((char *)ip6 + offset);
+
+ /* verify the version */
+ if (ph->version != PFSYNC_VERSION) {
+ V_pfsyncstats.pfsyncs_badver++;
+ goto done;
+ }
+
+ len = ntohs(ph->len) + offset;
+ if (m->m_pkthdr.len < len) {
+ V_pfsyncstats.pfsyncs_badlen++;
+ goto done;
+ }
+
+ /*
+ * Trusting pf_chksum during packet processing, as well as seeking
+ * in interface name tree, require holding PF_RULES_RLOCK().
+ */
+ PF_RULES_RLOCK();
+ if (!bcmp(&ph->pfcksum, &V_pf_status.pf_chksum, PF_MD5_DIGEST_LENGTH))
+ flags = PFSYNC_SI_CKSUM;
+
+ offset += sizeof(*ph);
+ while (offset <= len - sizeof(subh)) {
+ m_copydata(m, offset, sizeof(subh), (caddr_t)&subh);
+ offset += sizeof(subh);
+
+ if (subh.action >= PFSYNC_ACT_MAX) {
+ V_pfsyncstats.pfsyncs_badact++;
+ PF_RULES_RUNLOCK();
+ goto done;
+ }
+
+ count = ntohs(subh.count);
+ V_pfsyncstats.pfsyncs_iacts[subh.action] += count;
+ rv = (*pfsync_acts[subh.action])(m, offset, count, flags, subh.action);
+ if (rv == -1) {
+ PF_RULES_RUNLOCK();
+ return (IPPROTO_DONE);
+ }
+
+ offset += rv;
+ }
+ PF_RULES_RUNLOCK();
+
+done:
+ m_freem(m);
+ return (IPPROTO_DONE);
+}
+#endif
+
static int
pfsync_in_clr(struct mbuf *m, int offset, int count, int flags, int action)
{
@@ -1701,6 +1813,19 @@
ip_fillid(ip);
break;
}
+#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ struct ip6_hdr *ip6;
+
+ ip6 = mtod(m, struct ip6_hdr *);
+ bcopy(&sc->sc_template.ipv6, ip6, sizeof(*ip6));
+ aflen = offset = sizeof(*ip6);
+
+ ip6->ip6_plen = htons(m->m_pkthdr.len);
+ break;
+ }
#endif
default:
m_freem(m);
@@ -2512,10 +2637,8 @@
error = ip6_output(m, NULL, NULL, 0,
NULL, NULL, NULL);
} else {
- MPASS(false);
- /* We don't support pfsync over IPv6. */
- /*error = ip6_output(m, NULL, NULL,
- IP_RAWOUTPUT, &sc->sc_imo6, NULL);*/
+ error = ip6_output(m, NULL, NULL, 0,
+ &sc->sc_im6o, NULL, NULL);
}
break;
#endif
@@ -2564,10 +2687,12 @@
static int
pfsync_multicast_setup(struct pfsync_softc *sc, struct ifnet *ifp,
- struct in_mfilter *imf)
+ struct in_mfilter* imf, struct in6_mfilter* im6f)
{
struct ip_moptions *imo = &sc->sc_imo;
+ struct ip6_moptions *im6o = &sc->sc_im6o;
int error;
+ struct sockaddr_in6 *syncpeer_sa6 = NULL;
if (!(ifp->if_flags & IFF_MULTICAST))
return (EADDRNOTAVAIL);
@@ -2578,9 +2703,12 @@
{
ip_mfilter_init(&imo->imo_head);
imo->imo_multicast_vif = -1;
- if ((error = in_joingroup(ifp, &((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr, NULL,
- &imf->imf_inm)) != 0)
+ if ((error = in_joingroup(ifp,
+ &(((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr),
+ NULL, &imf->imf_inm)) != 0)
+ {
return (error);
+ }
ip_mfilter_insert(&imo->imo_head, imf);
imo->imo_multicast_ifp = ifp;
@@ -2589,7 +2717,29 @@
break;
}
#endif
+#ifdef INET6
+ case AF_INET6:
+ {
+ syncpeer_sa6 = (struct sockaddr_in6 *)&sc->sc_sync_peer;
+ if ((error = in6_setscope(&syncpeer_sa6->sin6_addr, ifp, NULL)))
+ {
+ return (error);
+ }
+ ip6_mfilter_init(&im6o->im6o_head);
+ if ((error = in6_joingroup(ifp, &syncpeer_sa6->sin6_addr, NULL,
+ &(im6f->im6f_in6m), 0)) != 0)
+ {
+ return (error);
+ }
+
+ ip6_mfilter_insert(&im6o->im6o_head, im6f);
+ im6o->im6o_multicast_ifp = ifp;
+ im6o->im6o_multicast_hlim = PFSYNC_DFLTTL;
+ im6o->im6o_multicast_loop = 0;
+ break;
+ }
}
+#endif
return (0);
}
@@ -2598,7 +2748,9 @@
pfsync_multicast_cleanup(struct pfsync_softc *sc)
{
struct ip_moptions *imo = &sc->sc_imo;
+ struct ip6_moptions *im6o = &sc->sc_im6o;
struct in_mfilter *imf;
+ struct in6_mfilter *im6f;
while ((imf = ip_mfilter_first(&imo->imo_head)) != NULL) {
ip_mfilter_remove(&imo->imo_head, imf);
@@ -2606,6 +2758,13 @@
ip_mfilter_free(imf);
}
imo->imo_multicast_ifp = NULL;
+
+ while ((im6f = ip6_mfilter_first(&im6o->im6o_head)) != NULL) {
+ ip6_mfilter_remove(&im6o->im6o_head, im6f);
+ in6_leavegroup(im6f->im6f_in6m, NULL);
+ ip6_mfilter_free(im6f);
+ }
+ im6o->im6o_multicast_ifp = NULL;
}
void
@@ -2625,6 +2784,7 @@
*/
ip_mfilter_init(&sc->sc_imo.imo_head);
sc->sc_imo.imo_multicast_ifp = NULL;
+ sc->sc_im6o.im6o_multicast_ifp = NULL;
sc->sc_sync_if = NULL;
}
@@ -2655,9 +2815,11 @@
static int
pfsync_kstatus_to_softc(struct pfsync_kstatus *status, struct pfsync_softc *sc)
{
- struct in_mfilter *imf = NULL;
struct ifnet *sifp;
- struct ip *ip;
+ struct in_mfilter *imf = NULL;
+ struct in6_mfilter *im6f = NULL;
+ struct sockaddr_in *status_sin;
+ struct sockaddr_in6 *status_sin6;
int error;
int c;
@@ -2669,12 +2831,45 @@
else if ((sifp = ifunit_ref(status->syncdev)) == NULL)
return (EINVAL);
- struct sockaddr_in *status_sin =
- (struct sockaddr_in *)&(status->syncpeer);
- if (sifp != NULL && (status_sin->sin_addr.s_addr == 0 ||
- status_sin->sin_addr.s_addr ==
- htonl(INADDR_PFSYNC_GROUP)))
- imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
+ switch (status->syncpeer.ss_family) {
+ case AF_UNSPEC:
+ case AF_INET: {
+ status_sin = (struct sockaddr_in *)&(status->syncpeer);
+ if (sifp != NULL) {
+ if (status_sin->sin_addr.s_addr == 0 ||
+ status_sin->sin_addr.s_addr ==
+ htonl(INADDR_PFSYNC_GROUP)) {
+ status_sin->sin_family = AF_INET;
+ status_sin->sin_len = sizeof(*status_sin);
+ status_sin->sin_addr.s_addr =
+ htonl(INADDR_PFSYNC_GROUP);
+ }
+
+ if (IN_MULTICAST(ntohl(status_sin->sin_addr.s_addr))) {
+ imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
+ }
+ }
+ break;
+ }
+ case AF_INET6: {
+ status_sin6 = (struct sockaddr_in6*)&(status->syncpeer);
+ if (sifp != NULL) {
+ if (IN6_IS_ADDR_UNSPECIFIED(&status_sin6->sin6_addr) ||
+ IN6_ARE_ADDR_EQUAL(&status_sin6->sin6_addr,
+ &in6addr_linklocal_pfsync_group)) {
+ status_sin6->sin6_family = AF_INET6;
+ status_sin6->sin6_len = sizeof(*status_sin6);
+ status_sin6->sin6_addr =
+ in6addr_linklocal_pfsync_group;
+ }
+
+ if (IN6_IS_ADDR_MULTICAST(&status_sin6->sin6_addr)) {
+ im6f = ip6_mfilter_alloc(M_WAITOK, 0, 0);
+ }
+ }
+ break;
+ }
+ }
PFSYNC_LOCK(sc);
@@ -2691,13 +2886,31 @@
return (EINVAL);
}
- struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer;
- sc_sin->sin_family = AF_INET;
- sc_sin->sin_len = sizeof(*sc_sin);
- if (status_sin->sin_addr.s_addr == 0) {
- sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
- } else {
- sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr;
+ switch (status->syncpeer.ss_family) {
+ case AF_INET: {
+ struct sockaddr_in *status_sin = (struct sockaddr_in *)&(status->syncpeer);
+ struct sockaddr_in *sc_sin = (struct sockaddr_in *)&sc->sc_sync_peer;
+ sc_sin->sin_family = AF_INET;
+ sc_sin->sin_len = sizeof(*sc_sin);
+ if (status_sin->sin_addr.s_addr == 0) {
+ sc_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
+ } else {
+ sc_sin->sin_addr.s_addr = status_sin->sin_addr.s_addr;
+ }
+ break;
+ }
+ case AF_INET6: {
+ struct sockaddr_in6 *status_sin = (struct sockaddr_in6 *)&(status->syncpeer);
+ struct sockaddr_in6 *sc_sin = (struct sockaddr_in6 *)&sc->sc_sync_peer;
+ sc_sin->sin6_family = AF_INET6;
+ sc_sin->sin6_len = sizeof(*sc_sin);
+ if(IN6_IS_ADDR_UNSPECIFIED(&status_sin->sin6_addr)) {
+ sc_sin->sin6_addr = in6addr_linklocal_pfsync_group;
+ } else {
+ sc_sin->sin6_addr = status_sin->sin6_addr;
+ }
+ break;
+ }
}
sc->sc_maxupdates = status->maxupdates;
@@ -2731,12 +2944,20 @@
pfsync_multicast_cleanup(sc);
- if (sc_sin->sin_addr.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
- error = pfsync_multicast_setup(sc, sifp, imf);
+ if (((sc->sc_sync_peer.ss_family == AF_INET) &&
+ IN_MULTICAST(ntohl(((struct sockaddr_in *)
+ &sc->sc_sync_peer)->sin_addr.s_addr))) ||
+ ((sc->sc_sync_peer.ss_family == AF_INET6) &&
+ IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)
+ &sc->sc_sync_peer)->sin6_addr))) {
+ error = pfsync_multicast_setup(sc, sifp, imf, im6f);
if (error) {
if_rele(sifp);
- ip_mfilter_free(imf);
PFSYNC_UNLOCK(sc);
+ if (imf != NULL)
+ ip_mfilter_free(imf);
+ if (im6f != NULL)
+ ip6_mfilter_free(im6f);
return (error);
}
}
@@ -2744,17 +2965,39 @@
if_rele(sc->sc_sync_if);
sc->sc_sync_if = sifp;
- ip = &sc->sc_template.ipv4;
- bzero(ip, sizeof(*ip));
- ip->ip_v = IPVERSION;
- ip->ip_hl = sizeof(sc->sc_template.ipv4) >> 2;
- ip->ip_tos = IPTOS_LOWDELAY;
- /* len and id are set later. */
- ip->ip_off = htons(IP_DF);
- ip->ip_ttl = PFSYNC_DFLTTL;
- ip->ip_p = IPPROTO_PFSYNC;
- ip->ip_src.s_addr = INADDR_ANY;
- ip->ip_dst.s_addr = sc_sin->sin_addr.s_addr;
+ switch (sc->sc_sync_peer.ss_family) {
+ case AF_INET: {
+ struct ip *ip;
+ ip = &sc->sc_template.ipv4;
+ bzero(ip, sizeof(*ip));
+ ip->ip_v = IPVERSION;
+ ip->ip_hl = sizeof(sc->sc_template.ipv4) >> 2;
+ ip->ip_tos = IPTOS_LOWDELAY;
+ /* len and id are set later. */
+ ip->ip_off = htons(IP_DF);
+ ip->ip_ttl = PFSYNC_DFLTTL;
+ ip->ip_p = IPPROTO_PFSYNC;
+ ip->ip_src.s_addr = INADDR_ANY;
+ ip->ip_dst = ((struct sockaddr_in *)&sc->sc_sync_peer)->sin_addr;
+ break;
+ }
+ case AF_INET6: {
+ struct ip6_hdr *ip6;
+ ip6 = &sc->sc_template.ipv6;
+ bzero(ip6, sizeof(*ip6));
+ ip6->ip6_vfc = IPV6_VERSION;
+ ip6->ip6_hlim = PFSYNC_DFLTTL;
+ ip6->ip6_nxt = IPPROTO_PFSYNC;
+ ip6->ip6_dst = ((struct sockaddr_in6 *)&sc->sc_sync_peer)->sin6_addr;
+
+ struct epoch_tracker et;
+ NET_EPOCH_ENTER(et);
+ in6_selectsrc_addr(if_getfib(sc->sc_sync_if), &ip6->ip6_dst, 0,
+ sc->sc_sync_if, &ip6->ip6_src, NULL);
+ NET_EPOCH_EXIT(et);
+ break;
+ }
+ }
/* Request a full state table update. */
if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p)
@@ -2841,15 +3084,22 @@
static int
pfsync_init(void)
{
-#ifdef INET
int error;
pfsync_detach_ifnet_ptr = pfsync_detach_ifnet;
+#ifdef INET
error = ipproto_register(IPPROTO_PFSYNC, pfsync_input, NULL);
if (error)
return (error);
#endif
+#ifdef INET6
+ error = ip6proto_register(IPPROTO_PFSYNC, pfsync6_input, NULL);
+ if (error) {
+ ipproto_unregister(IPPROTO_PFSYNC);
+ return (error);
+ }
+#endif
return (0);
}
@@ -2862,6 +3112,9 @@
#ifdef INET
ipproto_unregister(IPPROTO_PFSYNC);
#endif
+#ifdef INET6
+ ip6proto_unregister(IPPROTO_PFSYNC);
+#endif
}
static int
diff --git a/sys/netpfil/pf/pfsync_nv.c b/sys/netpfil/pf/pfsync_nv.c
--- a/sys/netpfil/pf/pfsync_nv.c
+++ b/sys/netpfil/pf/pfsync_nv.c
@@ -35,6 +35,11 @@
#include <sys/param.h>
#include <sys/errno.h>
+#include <netinet/in.h>
+
+#include <netinet6/ip6_var.h>
+#include <netinet6/scope6_var.h>
+
#include <netpfil/pf/pfsync_nv.h>
int
@@ -42,6 +47,7 @@
struct sockaddr_storage *sa)
{
int af;
+ int error;
if (!nvlist_exists_number(nvl, "af"))
return (EINVAL);
@@ -74,6 +80,11 @@
return (EINVAL);
memcpy(in6, addr, sizeof(*in6));
+
+ error = sa6_embedscope(in6, V_ip6_use_defzone);
+ if (error)
+ return (error);
+
break;
}
#endif
@@ -106,6 +117,7 @@
#ifdef INET6
case AF_INET6: {
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa;
+ sa6_recoverscope(in6);
nvlist_add_number(nvl, "af", in6->sin6_family);
nvlist_add_binary(nvl, "address", in6, sizeof(*in6));
break;
diff --git a/tests/sys/netpfil/pf/pfsync.sh b/tests/sys/netpfil/pf/pfsync.sh
--- a/tests/sys/netpfil/pf/pfsync.sh
+++ b/tests/sys/netpfil/pf/pfsync.sh
@@ -702,6 +702,130 @@
pft_cleanup
}
+atf_test_case "basic_ipv6_unicast" "cleanup"
+basic_ipv6_unicast_head()
+{
+ atf_set descr 'Basic pfsync test (IPv6)'
+ atf_set require.user root
+}
+
+basic_ipv6_unicast_body()
+{
+ pfsynct_init
+
+ epair_sync=$(vnet_mkepair)
+ epair_one=$(vnet_mkepair)
+ epair_two=$(vnet_mkepair)
+
+ vnet_mkjail one ${epair_one}a ${epair_sync}a
+ vnet_mkjail two ${epair_two}a ${epair_sync}b
+
+ # pfsync interface
+ jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up
+ jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up
+ jexec one ifconfig pfsync0 \
+ syncdev ${epair_sync}a \
+ syncpeer fd2c::2 \
+ maxupd 1 \
+ up
+ jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up
+ jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up
+ jexec two ifconfig pfsync0 \
+ syncdev ${epair_sync}b \
+ syncpeer fd2c::1 \
+ maxupd 1 \
+ up
+
+ # Enable pf!
+ jexec one pfctl -e
+ pft_set_rules one \
+ "block on ${epair_sync}a inet" \
+ "pass out keep state"
+ jexec two pfctl -e
+ pft_set_rules two \
+ "block on ${epair_sync}b inet" \
+ "pass out keep state"
+
+ ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up
+
+ ping6 -c 1 -S fd2b::f0 fd2b::1
+
+ # Give pfsync time to do its thing
+ sleep 2
+
+ if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \
+ grep fd2b::f0 ; then
+ atf_fail "state not found on synced host"
+ fi
+}
+
+basic_ipv6_unicast_cleanup()
+{
+ pfsynct_cleanup
+}
+
+atf_test_case "basic_ipv6" "cleanup"
+basic_ipv6_head()
+{
+ atf_set descr 'Basic pfsync test (IPv6)'
+ atf_set require.user root
+}
+
+basic_ipv6_body()
+{
+ pfsynct_init
+
+ epair_sync=$(vnet_mkepair)
+ epair_one=$(vnet_mkepair)
+ epair_two=$(vnet_mkepair)
+
+ vnet_mkjail one ${epair_one}a ${epair_sync}a
+ vnet_mkjail two ${epair_two}a ${epair_sync}b
+
+ # pfsync interface
+ jexec one ifconfig ${epair_sync}a inet6 fd2c::1/64 no_dad up
+ jexec one ifconfig ${epair_one}a inet6 fd2b::1/64 no_dad up
+ jexec one ifconfig pfsync0 \
+ syncdev ${epair_sync}a \
+ syncpeer ff12::f0 \
+ maxupd 1 \
+ up
+ jexec two ifconfig ${epair_two}a inet6 fd2b::2/64 no_dad up
+ jexec two ifconfig ${epair_sync}b inet6 fd2c::2/64 no_dad up
+ jexec two ifconfig pfsync0 \
+ syncdev ${epair_sync}b \
+ syncpeer ff12::f0 \
+ maxupd 1 \
+ up
+
+ # Enable pf!
+ jexec one pfctl -e
+ pft_set_rules one \
+ "block on ${epair_sync}a inet" \
+ "pass out keep state"
+ jexec two pfctl -e
+ pft_set_rules two \
+ "block on ${epair_sync}b inet" \
+ "pass out keep state"
+
+ ifconfig ${epair_one}b inet6 fd2b::f0/64 no_dad up
+
+ ping6 -c 1 -S fd2b::f0 fd2b::1
+
+ # Give pfsync time to do its thing
+ sleep 2
+
+ if ! jexec two pfctl -s states | grep icmp | grep fd2b::1 | \
+ grep fd2b::f0 ; then
+ atf_fail "state not found on synced host"
+ fi
+}
+
+basic_ipv6_cleanup()
+{
+ pfsynct_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "basic"
@@ -712,4 +836,6 @@
atf_add_test_case "pfsync_pbr"
atf_add_test_case "ipsec"
atf_add_test_case "timeout"
+ atf_add_test_case "basic_ipv6_unicast"
+ atf_add_test_case "basic_ipv6"
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 5, 5:23 AM (21 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16467908
Default Alt Text
D40102.diff (18 KB)
Attached To
Mode
D40102: pfsync: Transport over IPv6 Unicast support
Attached
Detach File
Event Timeline
Log In to Comment