Page MenuHomeFreeBSD

D40866.id124211.diff
No OneTemporary

D40866.id124211.diff

diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -444,6 +444,20 @@
VNET_DEFINE(uint32_t, pf_hashseed);
#define V_pf_hashseed VNET(pf_hashseed)
+#if defined(SCTP) || defined(SCTP_SUPPORT)
+static void
+pf_sctp_checksum(struct mbuf *m, int off)
+{
+ uint32_t sum = 0;
+
+ /* Zero out the checksum, to enable recalculation. */
+ m_copyback(m, off + offsetof(struct sctphdr, checksum),
+ sizeof(sum), (caddr_t)&sum);
+
+ sctp_delayed_cksum(m, off);
+}
+#endif
+
int
pf_addr_cmp(struct pf_addr *a, struct pf_addr *b, sa_family_t af)
{
@@ -517,6 +531,32 @@
m_copyback(m, off, sizeof(*uh), (caddr_t)uh);
break;
}
+#if defined(SCTP) || defined(SCTP_SUPPORT)
+ case IPPROTO_SCTP: {
+ struct sctphdr *sh = &pd->hdr.sctp;
+ uint16_t checksum = 0;
+ bool rewrite = false;
+
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af)) {
+ pf_change_ap(m, pd->src, &sh->src_port, pd->ip_sum,
+ &checksum, &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 1, pd->af);
+ rewrite = true;
+ }
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af)) {
+ pf_change_ap(m, pd->dst, &sh->dest_port, pd->ip_sum,
+ &checksum, &nk->addr[pd->didx],
+ nk->port[pd->didx], 1, pd->af);
+ rewrite = true;
+ }
+
+ if (rewrite) {
+ m_copyback(m, off, sizeof(*sh), (caddr_t)sh);
+ pf_sctp_checksum(m, off);
+ }
+ break;
+ }
+#endif
case IPPROTO_ICMP: {
struct icmp *ih = &pd->hdr.icmp;
@@ -4453,6 +4493,39 @@
}
rewrite++;
break;
+#if defined(SCTP) || defined(SCTP_SUPPORT)
+ case IPPROTO_SCTP: {
+ uint16_t checksum = 0;
+ bool changed = false;
+
+ if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) ||
+ nk->port[pd->sidx] != sport) {
+ pf_change_ap(m, saddr, &pd->hdr.sctp.src_port,
+ pd->ip_sum, &checksum,
+ &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 1, af);
+ sport = pd->hdr.sctp.src_port;
+ pd->sport = &pd->hdr.sctp.src_port;
+ changed = true;
+ }
+ if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) ||
+ nk->port[pd->didx] != dport) {
+ pf_change_ap(m, daddr, &pd->hdr.sctp.dest_port,
+ pd->ip_sum, &checksum,
+ &nk->addr[pd->didx],
+ nk->port[pd->didx], 1, af);
+ dport = pd->hdr.sctp.dest_port;
+ pd->dport = &pd->hdr.sctp.dest_port;
+ changed = true;
+ }
+
+ if (changed) {
+ pf_sctp_checksum(m, off);
+ rewrite++;
+ }
+ break;
+ }
+#endif
#ifdef INET
case IPPROTO_ICMP:
nk->port[0] = nk->port[1];
@@ -5790,6 +5863,7 @@
return (PF_PASS);
}
+#if defined(SCTP) || defined(SCTP_SUPPORT)
static int
pf_test_state_sctp(struct pf_kstate **state, int direction,
struct pfi_kkif *kif, struct mbuf *m, int off, void *h,
@@ -5847,8 +5921,37 @@
(*state)->expire = time_uptime;
+ /* translate source/destination address, if necessary */
+ if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) {
+ uint16_t checksum = 0;
+ struct pf_state_key *nk = (*state)->key[pd->didx];
+ bool changed = false;
+
+ if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) ||
+ nk->port[pd->sidx] != pd->hdr.sctp.src_port) {
+ pf_change_ap(m, pd->src, &pd->hdr.sctp.src_port,
+ pd->ip_sum, &checksum, &nk->addr[pd->sidx],
+ nk->port[pd->sidx], 1, pd->af);
+ changed = true;
+ }
+
+ if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) ||
+ nk->port[pd->didx] != pd->hdr.sctp.dest_port) {
+ pf_change_ap(m, pd->dst, &pd->hdr.sctp.dest_port,
+ pd->ip_sum, &checksum, &nk->addr[pd->didx],
+ nk->port[pd->didx], 1, pd->af);
+ changed = true;
+ }
+
+ if (changed) {
+ m_copyback(m, off, sizeof(pd->hdr.sctp), (caddr_t)&pd->hdr.sctp);
+ pf_sctp_checksum(m, off);
+ }
+ }
+
return (PF_PASS);
}
+#endif
static int
pf_test_state_icmp(struct pf_kstate **state, int direction, struct pfi_kkif *kif,
@@ -7575,6 +7678,7 @@
break;
}
+#if defined(SCTP) || defined(SCTP_SUPPORT)
case IPPROTO_SCTP: {
if (!pf_pull_hdr(m, off, &pd.hdr.sctp, sizeof(pd.hdr.sctp),
&action, &reason, AF_INET)) {
@@ -7606,6 +7710,7 @@
}
break;
}
+#endif
case IPPROTO_ICMP: {
if (!pf_pull_hdr(m, off, &pd.hdr.icmp, ICMP_MINLEN,
@@ -8165,6 +8270,7 @@
break;
}
+#if defined(SCTP) || defined(SCTP_SUPPORT)
case IPPROTO_SCTP: {
if (!pf_pull_hdr(m, off, &pd.hdr.sctp, sizeof(pd.hdr.sctp),
&action, &reason, AF_INET6)) {
@@ -8196,6 +8302,7 @@
}
break;
}
+#endif
case IPPROTO_ICMP: {
action = PF_DROP;

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 13, 2:03 PM (18 h, 31 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17136674
Default Alt Text
D40866.id124211.diff (4 KB)

Event Timeline