Page MenuHomeFreeBSD

D40102.id122717.diff
No OneTemporary

D40102.id122717.diff

diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c
--- a/sbin/ifconfig/ifpfsync.c
+++ b/sbin/ifconfig/ifpfsync.c
@@ -234,12 +234,18 @@
struct sockaddr_in *sin = (struct sockaddr_in *)
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 = (struct sockaddr_in6 *)
+ peerres->ai_addr;
+
+ memcpy(&addr, sin6, sizeof(*sin6));
+ break;
+ }
#endif
default:
errx(1, "syncpeer address %s not supported", val);
@@ -363,9 +369,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 ( \
@@ -215,6 +220,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;
@@ -265,8 +271,7 @@
static void pfsync_push(struct pfsync_bucket *);
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);
+static int pfsync_multicast_setup(struct pfsync_softc *, struct ifnet *);
static void pfsync_multicast_cleanup(struct pfsync_softc *);
static void pfsync_pointers_init(void);
static void pfsync_pointers_uninit(void);
@@ -330,6 +335,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)
{
@@ -761,6 +769,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);
+ 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)
{
@@ -1585,6 +1696,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);
@@ -2357,10 +2481,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
@@ -2408,11 +2530,14 @@
}
static int
-pfsync_multicast_setup(struct pfsync_softc *sc, struct ifnet *ifp,
- struct in_mfilter *imf)
+pfsync_multicast_setup(struct pfsync_softc *sc, struct ifnet *ifp)
{
struct ip_moptions *imo = &sc->sc_imo;
+ struct ip6_moptions *im6o = &sc->sc_im6o;
int error;
+ struct in_mfilter *imf = NULL;
+ struct in6_mfilter *im6f = NULL;
+ struct sockaddr_in6 *syncpeer_sa6 = NULL;
if (!(ifp->if_flags & IFF_MULTICAST))
return (EADDRNOTAVAIL);
@@ -2421,11 +2546,15 @@
#ifdef INET
case AF_INET:
{
+ imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
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)
+ {
+ ip_mfilter_free(imf);
return (error);
+ }
ip_mfilter_insert(&imo->imo_head, imf);
imo->imo_multicast_ifp = ifp;
@@ -2434,7 +2563,30 @@
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);
+ }
+ im6f = ip6_mfilter_alloc(M_WAITOK, 0, 0);
+ ip6_mfilter_init(&im6o->im6o_head);
+ if ((error = in6_joingroup(ifp, &syncpeer_sa6->sin6_addr, NULL,
+ &(im6f->im6f_in6m), 0)))
+ {
+ ip6_mfilter_free(im6f);
+ 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);
}
@@ -2443,7 +2595,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);
@@ -2451,6 +2605,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
@@ -2470,6 +2631,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;
}
@@ -2500,9 +2662,7 @@
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;
int error;
int c;
@@ -2514,21 +2674,50 @@
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: {
+ 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))) {
+ status_sin->sin_family = AF_INET;
+ status_sin->sin_len = sizeof(*status_sin);
+ status_sin->sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
+ }
+ break;
+ }
+ case AF_INET6: {
+ struct sockaddr_in6 *status_sin6 = (struct sockaddr_in6*)&(status->syncpeer);
+ if (sifp != NULL &&
+ (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;
+ }
+ break;
+ }
+ }
PFSYNC_LOCK(sc);
- 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);
+ sc_sin->sin_addr = status_sin->sin_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);
+ sc_sin->sin6_addr = status_sin->sin6_addr;
+ break;
+ }
}
sc->sc_maxupdates = status->maxupdates;
@@ -2562,11 +2751,15 @@
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);
if (error) {
if_rele(sifp);
- ip_mfilter_free(imf);
PFSYNC_UNLOCK(sc);
return (error);
}
@@ -2575,17 +2768,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)
@@ -2672,15 +2887,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);
}
@@ -2693,6 +2915,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 fc2c::1/64 up
+ jexec one ifconfig ${epair_one}a inet6 fc2b::1/64 up
+ jexec one ifconfig pfsync0 \
+ syncdev ${epair_sync}a \
+ syncpeer fc2c::2 \
+ maxupd 1 \
+ up
+ jexec two ifconfig ${epair_two}a inet6 fc2b::2/64 up
+ jexec two ifconfig ${epair_sync}b inet6 fc2c::2/64 up
+ jexec two ifconfig pfsync0 \
+ syncdev ${epair_sync}b \
+ syncpeer fc2c::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 fc2b::f0/64 up
+
+ ping6 -c 1 -S fc2b::f0 fc2b::1
+
+ # Give pfsync time to do its thing
+ sleep 2
+
+ if ! jexec two pfctl -s states | grep icmp | grep fc2b::1 | \
+ grep fc2b::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 fc2c::1/64 up
+ jexec one ifconfig ${epair_one}a inet6 fc2b::1/64 up
+ jexec one ifconfig pfsync0 \
+ syncdev ${epair_sync}a \
+ syncpeer ff12::f0 \
+ maxupd 1 \
+ up
+ jexec two ifconfig ${epair_two}a inet6 fc2b::2/64 up
+ jexec two ifconfig ${epair_sync}b inet6 fc2c::2/64 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 fc2b::f0/64 up
+
+ ping6 -c 1 -S fc2b::f0 fc2b::1
+
+ # Give pfsync time to do its thing
+ sleep 2
+
+ if ! jexec two pfctl -s states | grep icmp | grep fc2b::1 | \
+ grep fc2b::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

Mime Type
text/plain
Expires
Sun, Apr 19, 2:09 PM (20 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31775589
Default Alt Text
D40102.id122717.diff (17 KB)

Event Timeline