Page MenuHomeFreeBSD

D36277.id109628.diff
No OneTemporary

D36277.id109628.diff

diff --git a/sbin/ifconfig/ifpfsync.c b/sbin/ifconfig/ifpfsync.c
--- a/sbin/ifconfig/ifpfsync.c
+++ b/sbin/ifconfig/ifpfsync.c
@@ -97,7 +97,7 @@
setpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
{
struct pfsyncreq preq;
- struct addrinfo hints, *peerres;
+ struct addrinfo *peerres;
int ecode;
bzero((char *)&preq, sizeof(struct pfsyncreq));
@@ -106,19 +106,25 @@
if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
err(1, "SIOCGETPFSYNC");
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
-
- if ((ecode = getaddrinfo(val, NULL, &hints, &peerres)) != 0)
+ if ((ecode = getaddrinfo(val, NULL, NULL, &peerres)) != 0)
errx(1, "error in parsing address string: %s",
gai_strerror(ecode));
- if (peerres->ai_addr->sa_family != AF_INET)
- errx(1, "only IPv4 addresses supported for the syncpeer");
+ switch (peerres->ai_family) {
+#ifdef INET
+ case AF_INET: {
+ 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");
- preq.pfsyncr_syncpeer.s_addr = ((struct sockaddr_in *)
- peerres->ai_addr)->sin_addr.s_addr;
+ preq.pfsyncr_syncpeer.in4 = *sin;
+ break;
+ }
+#endif
+ default:
+ errx(1, "syncpeer address %s not supported", val);
+ }
if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
err(1, "SIOCSETPFSYNC");
@@ -137,7 +143,16 @@
if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
err(1, "SIOCGETPFSYNC");
- preq.pfsyncr_syncpeer.s_addr = 0;
+ switch (preq.pfsyncr_syncpeer.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+#endif
+ {
+ bzero((char *)&preq.pfsyncr_syncpeer,
+ sizeof(union pfsync_sockaddr));
+ break;
+ }
+ }
if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
err(1, "SIOCSETPFSYNC");
@@ -187,24 +202,35 @@
pfsync_status(int s)
{
struct pfsyncreq preq;
+ char syncpeer[NI_MAXHOST];
+ struct sockaddr *syncpeer_sa;
+ int error;
bzero((char *)&preq, sizeof(struct pfsyncreq));
ifr.ifr_data = (caddr_t)&preq;
+ syncpeer_sa = &preq.pfsyncr_syncpeer.sa;
if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
return;
if (preq.pfsyncr_syncdev[0] != '\0' ||
- preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP))
- printf("\t");
+ syncpeer_sa->sa_family != AF_UNSPEC)
+ printf("\t");
if (preq.pfsyncr_syncdev[0] != '\0')
- printf("pfsync: syncdev: %s ", preq.pfsyncr_syncdev);
- if (preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP))
- printf("syncpeer: %s ", inet_ntoa(preq.pfsyncr_syncpeer));
+ printf("syncdev: %s ", preq.pfsyncr_syncdev);
+
+ if (preq.pfsyncr_syncpeer.sa.sa_family != AF_UNSPEC &&
+ preq.pfsyncr_syncpeer.in4.sin_addr.s_addr != htonl(INADDR_PFSYNC_GROUP)) {
+ if ((error = getnameinfo(syncpeer_sa, syncpeer_sa->sa_len,
+ syncpeer, sizeof(syncpeer), NULL, 0, NI_NUMERICHOST)) != 0)
+ errx(1, "getnameinfo: %s", gai_strerror(error));
+ printf("syncpeer: %s ", syncpeer);
+ }
if (preq.pfsyncr_syncdev[0] != '\0' ||
- preq.pfsyncr_syncpeer.s_addr != htonl(INADDR_PFSYNC_GROUP)) {
+ (preq.pfsyncr_syncpeer.sa.sa_family != AF_UNSPEC &&
+ preq.pfsyncr_syncpeer.in4.sin_addr.s_addr != htonl(INADDR_PFSYNC_GROUP))) {
printf("maxupd: %d ", preq.pfsyncr_maxupdates);
printf("defer: %s\n",
(preq.pfsyncr_defer & PFSYNCF_DEFER) ? "on" : "off");
diff --git a/sys/net/if_pfsync.h b/sys/net/if_pfsync.h
--- a/sys/net/if_pfsync.h
+++ b/sys/net/if_pfsync.h
@@ -54,6 +54,7 @@
#include <net/if.h>
#include <net/pfvar.h>
+#include <netinet/in.h>
#include <netpfil/pf/pf.h>
#define PFSYNC_VERSION 5
@@ -235,16 +236,21 @@
u_int64_t pfsyncs_oacts[PFSYNC_ACT_MAX];
};
+union pfsync_sockaddr {
+ struct sockaddr sa;
+ struct sockaddr_in in4;
+};
+
/*
* Configuration structure for SIOCSETPFSYNC SIOCGETPFSYNC
*/
struct pfsyncreq {
- char pfsyncr_syncdev[IFNAMSIZ];
- struct in_addr pfsyncr_syncpeer;
- int pfsyncr_maxupdates;
+ char pfsyncr_syncdev[IFNAMSIZ];
+ union pfsync_sockaddr pfsyncr_syncpeer;
+ int pfsyncr_maxupdates;
#define PFSYNCF_OK 0x00000001
#define PFSYNCF_DEFER 0x00000002
- int pfsyncr_defer;
+ int pfsyncr_defer;
};
#define SIOCSETPFSYNC _IOW('i', 247, struct ifreq)
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
@@ -89,6 +89,7 @@
#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>
@@ -101,16 +102,23 @@
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
+struct pfsync_bucket;
+
+union inet_template {
+ struct ip ipv4;
+};
+
#define PFSYNC_MINPKT ( \
- sizeof(struct ip) + \
+ sizeof(union inet_template) + \
sizeof(struct pfsync_header) + \
sizeof(struct pfsync_subheader) )
-struct pfsync_bucket;
-
struct pfsync_pkt {
- struct ip *ip;
- struct in_addr src;
+#ifdef INET
+ struct ip *ip4;
+ struct in_addr src4;
+#endif
+ sa_family_t af;
u_int8_t flags;
};
@@ -212,10 +220,10 @@
struct ifnet *sc_ifp;
struct ifnet *sc_sync_if;
struct ip_moptions sc_imo;
- struct in_addr sc_sync_peer;
+ union pfsync_sockaddr sc_sync_peer;
uint32_t sc_flags;
uint8_t sc_maxupdates;
- struct ip sc_template;
+ union inet_template sc_template;
struct mtx sc_mtx;
/* Queued data */
@@ -622,6 +630,7 @@
return (error);
}
+#ifdef INET
static int
pfsync_input(struct mbuf **mp, int *offp __unused, int proto __unused)
{
@@ -688,8 +697,10 @@
}
/* Cheaper to grab this now than having to mess with mbufs later */
- pkt.ip = ip;
- pkt.src = ip->ip_src;
+ // XXX: Is this even needed? Except for flags, other values seem unused
+ pkt.af = AF_INET;
+ pkt.ip4 = ip;
+ pkt.src4 = ip->ip_src;
pkt.flags = 0;
/*
@@ -727,6 +738,7 @@
m_freem(m);
return (IPPROTO_DONE);
}
+#endif
static int
pfsync_in_clr(struct pfsync_pkt *pkt, struct mbuf *m, int offset, int count)
@@ -1368,7 +1380,6 @@
{
struct in_mfilter *imf = NULL;
struct ifnet *sifp;
- struct ip *ip;
if ((error = priv_check(curthread, PRIV_NETINET_PF)) != 0)
return (error);
@@ -1383,19 +1394,19 @@
sifp = NULL;
else if ((sifp = ifunit_ref(pfsyncr.pfsyncr_syncdev)) == NULL)
return (EINVAL);
-
- if (sifp != NULL && (
- pfsyncr.pfsyncr_syncpeer.s_addr == 0 ||
- pfsyncr.pfsyncr_syncpeer.s_addr ==
- htonl(INADDR_PFSYNC_GROUP)))
+ if (sifp != NULL && (sc->sc_sync_peer.sa.sa_family == AF_UNSPEC)) {
imf = ip_mfilter_alloc(M_WAITOK, 0, 0);
+ }
PFSYNC_LOCK(sc);
- if (pfsyncr.pfsyncr_syncpeer.s_addr == 0)
- sc->sc_sync_peer.s_addr = htonl(INADDR_PFSYNC_GROUP);
- else
- sc->sc_sync_peer.s_addr =
- pfsyncr.pfsyncr_syncpeer.s_addr;
+ if (sifp != NULL && (sc->sc_sync_peer.sa.sa_family == AF_UNSPEC)) {
+ struct sockaddr_in peer_addr;
+ peer_addr.sin_family = AF_INET;
+ peer_addr.sin_addr.s_addr = htonl(INADDR_PFSYNC_GROUP);
+ sc->sc_sync_peer.in4 = peer_addr;
+
+ } else
+ sc->sc_sync_peer = pfsyncr.pfsyncr_syncpeer;
sc->sc_maxupdates = pfsyncr.pfsyncr_maxupdates;
if (pfsyncr.pfsyncr_defer & PFSYNCF_DEFER) {
@@ -1428,7 +1439,7 @@
pfsync_multicast_cleanup(sc);
- if (sc->sc_sync_peer.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
+ if (sc->sc_sync_peer.in4.sin_addr.s_addr == htonl(INADDR_PFSYNC_GROUP)) {
error = pfsync_multicast_setup(sc, sifp, imf);
if (error) {
if_rele(sifp);
@@ -1441,17 +1452,26 @@
if_rele(sc->sc_sync_if);
sc->sc_sync_if = sifp;
- ip = &sc->sc_template;
- bzero(ip, sizeof(*ip));
- ip->ip_v = IPVERSION;
- ip->ip_hl = sizeof(sc->sc_template) >> 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->sc_sync_peer.s_addr;
+ switch (sc->sc_sync_peer.sa.sa_family) {
+#ifdef INET
+ 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.s_addr =
+ sc->sc_sync_peer.in4.sin_addr.s_addr;
+ break;
+ }
+#endif
+ }
/* Request a full state table update. */
if ((sc->sc_flags & PFSYNCF_OK) && carp_demote_adj_p)
@@ -1559,13 +1579,12 @@
struct pfsync_softc *sc = V_pfsyncif;
struct ifnet *ifp = sc->sc_ifp;
struct mbuf *m;
- struct ip *ip;
struct pfsync_header *ph;
struct pfsync_subheader *subh;
struct pf_kstate *st, *st_next;
struct pfsync_upd_req_item *ur;
struct pfsync_bucket *b = &sc->sc_buckets[c];
- int offset;
+ int aflen, offset;
int q, count = 0;
KASSERT(sc != NULL, ("%s: null sc", __func__));
@@ -1588,12 +1607,23 @@
m->m_len = m->m_pkthdr.len = b->b_len;
/* build the ip header */
- ip = (struct ip *)m->m_data;
- bcopy(&sc->sc_template, ip, sizeof(*ip));
- offset = sizeof(*ip);
+ switch (sc->sc_sync_peer.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ struct ip *ip;
+
+ ip = mtod(m, struct ip *);
+ bcopy(&sc->sc_template.ipv4, ip, sizeof(*ip));
+ aflen = offset = sizeof(*ip);
+
+ ip->ip_len = htons(m->m_pkthdr.len);
+ ip_fillid(ip);
+ break;
+#endif
+ default:
+ return;
+ }
- ip->ip_len = htons(m->m_pkthdr.len);
- ip_fillid(ip);
/* build the pfsync header */
ph = (struct pfsync_header *)(m->m_data + offset);
@@ -1601,7 +1631,7 @@
offset += sizeof(*ph);
ph->version = PFSYNC_VERSION;
- ph->len = htons(b->b_len - sizeof(*ip));
+ ph->len = htons(b->b_len - aflen);
bcopy(V_pf_status.pf_chksum, ph->pfcksum, PF_MD5_DIGEST_LENGTH);
/* walk the queues */
@@ -1674,10 +1704,10 @@
/* we're done, let's put it on the wire */
if (ifp->if_bpf) {
- m->m_data += sizeof(*ip);
- m->m_len = m->m_pkthdr.len = b->b_len - sizeof(*ip);
+ m->m_data += aflen;
+ m->m_len = m->m_pkthdr.len = b->b_len - aflen;
BPF_MTAP(ifp, m);
- m->m_data -= sizeof(*ip);
+ m->m_data -= aflen;
m->m_len = m->m_pkthdr.len = b->b_len;
}
@@ -1830,7 +1860,13 @@
free(pd, M_PFSYNC);
PFSYNC_BUCKET_UNLOCK(b);
- ip_output(m, NULL, NULL, 0, NULL, NULL);
+ switch (sc->sc_sync_peer.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ ip_output(m, NULL, NULL, 0, NULL, NULL);
+ break;
+#endif
+ }
pf_release_state(st);
@@ -2320,7 +2356,7 @@
struct pfsync_softc *sc = arg;
struct pfsync_bucket *b;
struct mbuf *m, *n;
- int c;
+ int c, error;
NET_EPOCH_ENTER(et);
CURVNET_SET(sc->sc_ifp->if_vnet);
@@ -2345,10 +2381,21 @@
* own pfsync packet based on M_SKIP_FIREWALL
* flag. This is XXX.
*/
- if (m->m_flags & M_SKIP_FIREWALL)
- ip_output(m, NULL, NULL, 0, NULL, NULL);
- else if (ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo,
- NULL) == 0)
+ switch (sc->sc_sync_peer.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ if (m->m_flags & M_SKIP_FIREWALL) {
+ error = ip_output(m, NULL, NULL, 0,
+ NULL, NULL);
+ } else {
+ error = ip_output(m, NULL, NULL,
+ IP_RAWOUTPUT, &sc->sc_imo, NULL);
+ }
+ break;
+#endif
+ }
+
+ if (error == 0)
V_pfsyncstats.pfsyncs_opackets++;
else
V_pfsyncstats.pfsyncs_oerrors++;
@@ -2368,17 +2415,24 @@
if (!(ifp->if_flags & IFF_MULTICAST))
return (EADDRNOTAVAIL);
- imo->imo_multicast_vif = -1;
-
- if ((error = in_joingroup(ifp, &sc->sc_sync_peer, NULL,
- &imf->imf_inm)) != 0)
- return (error);
+ switch (sc->sc_sync_peer.sa.sa_family) {
+#ifdef INET
+ case AF_INET:
+ {
+ ip_mfilter_init(&imo->imo_head);
+ imo->imo_multicast_vif = -1;
+ if ((error = in_joingroup(ifp, &sc->sc_sync_peer.in4.sin_addr, NULL,
+ &imf->imf_inm)) != 0)
+ return (error);
- ip_mfilter_init(&imo->imo_head);
- ip_mfilter_insert(&imo->imo_head, imf);
- imo->imo_multicast_ifp = ifp;
- imo->imo_multicast_ttl = PFSYNC_DFLTTL;
- imo->imo_multicast_loop = 0;
+ ip_mfilter_insert(&imo->imo_head, imf);
+ imo->imo_multicast_ifp = ifp;
+ imo->imo_multicast_ttl = PFSYNC_DFLTTL;
+ imo->imo_multicast_loop = 0;
+ break;
+ }
+#endif
+ }
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 28, 2:43 PM (21 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16886722
Default Alt Text
D36277.id109628.diff (12 KB)

Event Timeline