Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F111113061
D36277.id109628.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D36277.id109628.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
@@ -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
Details
Attached
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)
Attached To
Mode
D36277: pfsync: Prepare code to accommodate AF_INET6 family
Attached
Detach File
Event Timeline
Log In to Comment