diff options
author | Guido van Rooij <guido@FreeBSD.org> | 2005-12-30 11:32:23 +0000 |
---|---|---|
committer | Guido van Rooij <guido@FreeBSD.org> | 2005-12-30 11:32:23 +0000 |
commit | 9088f4e67b87cf0d6e1b74723daa4206fd49dc35 (patch) | |
tree | 9d9609ac6630c945d00f5af3ce25a44c0a031d15 /sys/contrib/ipfilter/netinet/ip_nat.c | |
parent | 6afb2250fbb0338d050b74e265d0f7dfbb90d52f (diff) | |
download | src-9088f4e67b87cf0d6e1b74723daa4206fd49dc35.tar.gz src-9088f4e67b87cf0d6e1b74723daa4206fd49dc35.zip |
Resolve conflicts
Notes
Notes:
svn path=/head/; revision=153876
Diffstat (limited to 'sys/contrib/ipfilter/netinet/ip_nat.c')
-rw-r--r-- | sys/contrib/ipfilter/netinet/ip_nat.c | 101 |
1 files changed, 70 insertions, 31 deletions
diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index 83464d416619..1b69f853077c 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -37,7 +37,9 @@ struct file; #else # include <sys/ioctl.h> #endif -#include <sys/fcntl.h> +#if !defined(AIX) +# include <sys/fcntl.h> +#endif #if !defined(linux) # include <sys/protosw.h> #endif @@ -187,15 +189,15 @@ static INLINE int nat_newrdr __P((fr_info_t *, nat_t *, natinfo_t *)); static hostmap_t *nat_hostmap __P((ipnat_t *, struct in_addr, struct in_addr, struct in_addr, u_32_t)); static void nat_hostmapdel __P((struct hostmap *)); -static INLINE int nat_icmpquerytype4 __P((int)); +static int nat_icmpquerytype4 __P((int)); static int nat_siocaddnat __P((ipnat_t *, ipnat_t **, int)); static void nat_siocdelnat __P((ipnat_t *, ipnat_t **, int)); -static INLINE int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, +static int nat_finalise __P((fr_info_t *, nat_t *, natinfo_t *, tcphdr_t *, nat_t **, int)); static void nat_resolverule __P((ipnat_t *)); static nat_t *fr_natclone __P((fr_info_t *, nat_t *)); static void nat_mssclamp __P((tcphdr_t *, u_32_t, fr_info_t *, u_short *)); -static INLINE int nat_wildok __P((nat_t *, int, int, int, int)); +static int nat_wildok __P((nat_t *, int, int, int, int)); /* ------------------------------------------------------------------------ */ @@ -800,10 +802,14 @@ int mode; error = appr_ioctl(data, cmd, mode); break; case SIOCSTLCK : - fr_lock(data, &fr_nat_lock); + if (!(mode & FWRITE)) { + error = EPERM; + } else { + fr_lock(data, &fr_nat_lock); + } break; case SIOCSTPUT : - if (fr_nat_lock) { + if ((mode & FWRITE) != 0) { error = fr_natputent(data, getlock); } else { error = EACCES; @@ -1347,8 +1353,15 @@ int getlock; fin.fin_data[0] = ntohs(nat->nat_oport); fin.fin_data[1] = ntohs(nat->nat_outport); fin.fin_ifp = nat->nat_ifps[1]; - if (nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip, - nat->nat_inip) != NULL) { + if (getlock) { + READ_ENTER(&ipf_nat); + } + n = nat_inlookup(&fin, 0, fin.fin_p, nat->nat_oip, + nat->nat_inip); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } + if (n != NULL) { error = EEXIST; goto junkput; } @@ -1356,8 +1369,15 @@ int getlock; fin.fin_data[0] = ntohs(nat->nat_outport); fin.fin_data[1] = ntohs(nat->nat_oport); fin.fin_ifp = nat->nat_ifps[0]; - if (nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip, - nat->nat_oip) != NULL) { + if (getlock) { + READ_ENTER(&ipf_nat); + } + n = nat_outlookup(&fin, 0, fin.fin_p, nat->nat_outip, + nat->nat_oip); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } + if (n != NULL) { error = EEXIST; goto junkput; } @@ -1421,7 +1441,9 @@ int getlock; MUTEX_NUKE(&fr->fr_lock); MUTEX_INIT(&fr->fr_lock, "nat-filter rule lock"); } else { - READ_ENTER(&ipf_nat); + if (getlock) { + READ_ENTER(&ipf_nat); + } for (n = nat_instances; n; n = n->nat_next) if (n->nat_fr == fr) break; @@ -1431,7 +1453,9 @@ int getlock; fr->fr_ref++; MUTEX_EXIT(&fr->fr_lock); } - RWLOCK_EXIT(&ipf_nat); + if (getlock) { + RWLOCK_EXIT(&ipf_nat); + } if (!n) { error = ESRCH; @@ -1982,8 +2006,8 @@ natinfo_t *ni; * packet might match a different one to the previous connection but * we want the same destination to be used. */ - if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == - (IPN_ROUNDR|IPN_STICKY)) { + if (((np->in_flags & (IPN_ROUNDR|IPN_SPLIT)) != 0) && + ((np->in_flags & IPN_STICKY) != 0)) { hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, (u_32_t)dport); if (hm != NULL) { @@ -2004,7 +2028,7 @@ natinfo_t *ni; in.s_addr = np->in_nip; if ((np->in_flags & (IPN_ROUNDR|IPN_STICKY)) == IPN_STICKY) { - hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, + hm = nat_hostmap(NULL, fin->fin_src, fin->fin_dst, in, (u_32_t)dport); if (hm != NULL) { in.s_addr = hm->hm_mapip.s_addr; @@ -2077,6 +2101,9 @@ natinfo_t *ni; nat->nat_inip.s_addr = htonl(in.s_addr); nat->nat_outip = fin->fin_dst; nat->nat_oip = fin->fin_src; + if ((nat->nat_hm == NULL) && ((np->in_flags & IPN_STICKY) != 0)) + nat->nat_hm = nat_hostmap(np, fin->fin_src, fin->fin_dst, in, + (u_32_t)dport); ni->nai_sum1 = LONG_SUM(ntohl(fin->fin_daddr)) + ntohs(dport); ni->nai_sum2 = LONG_SUM(in.s_addr) + ntohs(nport); @@ -2338,7 +2365,7 @@ done: /* for both IPv4 and IPv6. */ /* ------------------------------------------------------------------------ */ /*ARGSUSED*/ -static INLINE int nat_finalise(fin, nat, ni, tcp, natsave, direction) +static int nat_finalise(fin, nat, ni, tcp, natsave, direction) fr_info_t *fin; nat_t *nat; natinfo_t *ni; @@ -2363,8 +2390,6 @@ int direction; nat->nat_ptr = np; nat->nat_p = fin->fin_p; nat->nat_mssclamp = np->in_mssclamp; - fr = fin->fin_fr; - nat->nat_fr = fr; if ((np->in_apr != NULL) && ((ni->nai_flags & NAT_SLAVE) == 0)) if (appr_new(fin, nat) == -1) @@ -2374,6 +2399,8 @@ int direction; if (nat_logging) nat_log(nat, (u_int)np->in_redir); np->in_use++; + fr = fin->fin_fr; + nat->nat_fr = fr; if (fr != NULL) { MUTEX_ENTER(&fr->fr_lock); fr->fr_ref++; @@ -2515,8 +2542,7 @@ int dir; * Only a basic IP header (no options) should be with an ICMP error * header. Also, if it's not an error type, then return. */ - if ((fin->fin_hlen != sizeof(ip_t)) || - !fr_icmp4errortype(type)) + if ((fin->fin_hlen != sizeof(ip_t)) || !(fin->fin_flx & FI_ICMPERR)) return NULL; /* @@ -3806,8 +3832,15 @@ u_32_t nflags; CALC_SUMD(s1, s2, sumd); fix_outcksum(fin, &fin->fin_ip->ip_sum, sumd); } -#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || defined(linux) +#if !defined(_KERNEL) || defined(MENTAT) || defined(__sgi) || \ + defined(linux) || defined(BRIDGE_IPF) else { + /* + * Strictly speaking, this isn't necessary on BSD + * kernels because they do checksum calculation after + * this code has run BUT if ipfilter is being used + * to do NAT as a bridge, that code doesn't exist. + */ if (nat->nat_dir == NAT_OUTBOUND) fix_outcksum(fin, &fin->fin_ip->ip_sum, nat->nat_ipsumd); @@ -4316,9 +4349,7 @@ void fr_natexpire() { ipftq_t *ifq, *ifqnext; ipftqent_t *tqe, *tqn; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif + SPL_INT(s); int i; SPL_NET(s); @@ -4373,9 +4404,7 @@ void *ifp; ipnat_t *n; nat_t *nat; void *ifp2; -#if defined(_KERNEL) && !defined(MENTAT) && defined(USE_SPL) - int s; -#endif + SPL_INT(s); if (fr_running <= 0) return; @@ -4457,7 +4486,7 @@ void *ifp; /* Tests to see if the ICMP type number passed is a query/response type or */ /* not. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_icmpquerytype4(icmptype) +static int nat_icmpquerytype4(icmptype) int icmptype; { @@ -4610,9 +4639,20 @@ nat_t *nat; MUTEX_NUKE(&clone->nat_lock); + clone->nat_aps = NULL; + /* + * Initialize all these so that nat_delete() doesn't cause a crash. + */ + clone->nat_tqe.tqe_pnext = NULL; + clone->nat_tqe.tqe_next = NULL; + clone->nat_tqe.tqe_ifq = NULL; + clone->nat_tqe.tqe_parent = clone; + clone->nat_flags &= ~SI_CLONE; clone->nat_flags |= SI_CLONED; + if (clone->nat_hm) + clone->nat_hm->hm_ref++; if (nat_insert(clone, fin->fin_rev) == -1) { KFREE(clone); @@ -4631,14 +4671,13 @@ nat_t *nat; MUTEX_EXIT(&fr->fr_lock); } - /* * Because the clone is created outside the normal loop of things and * TCP has special needs in terms of state, initialise the timeout * state of the new NAT from here. */ if (clone->nat_p == IPPROTO_TCP) { - (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, \ + (void) fr_tcp_age(&clone->nat_tqe, fin, nat_tqb, clone->nat_flags); } #ifdef IPFILTER_SYNC @@ -4663,7 +4702,7 @@ nat_t *nat; /* Use NAT entry and packet direction to determine which combination of */ /* wildcard flags should be used. */ /* ------------------------------------------------------------------------ */ -static INLINE int nat_wildok(nat, sport, dport, flags, dir) +static int nat_wildok(nat, sport, dport, flags, dir) nat_t *nat; int sport; int dport; |