Re: IPsec forward policy check in ip6_input
On Thu, May 11, 2017 at 01:36:51PM +0200, Mike Belopuhov wrote: > Maybe we should move ip_input_ipsec_fwd_check into the ipsec_input.c > and give it a better name like ipsec_forward_check? This function > doesn't do any IPv4 or IPv6 specific dances anyways. There are more such functions: ip_output_ipsec_lookup ip_output_ipsec_send ip6_output_ipsec_lookup ip6_output_ipsec_send ip_input_ipsec_fwd_check ip_input_ipsec_ours_check Some of them can be made independent of the address family. Then we can move all of them to a better home. bluhm > But I agree with you in principle. So would like commit this step. ip_input_ipsec_ours_check() is next on my list. Currently IPv6 is less strict than IPv4. But tcp_input() and udp_input() do the same check gain, but without calling a function. That is the rason why tcp, tcp6, udp, udp6 behave like ping, but ping6 is different. bluhm
Re: IPsec forward policy check in ip6_input
On Thu, May 11, 2017 at 13:11 +0200, Alexander Bluhm wrote: > Hi, > > ipv4_input() checks the IPsec policy for forwarding and local > delivery. Such code is missing in IPv6, the behavior is different. > > Start using the forwarding check also in ip6_input(). While there > avoid an ugly #ifdef in ipv4_input(). > > ok? > Maybe we should move ip_input_ipsec_fwd_check into the ipsec_input.c and give it a better name like ipsec_forward_check? This function doesn't do any IPv4 or IPv6 specific dances anyways. But I agree with you in principle. > bluhm > > Index: netinet/ip_input.c > === > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v > retrieving revision 1.298 > diff -u -p -r1.298 ip_input.c > --- netinet/ip_input.c19 Apr 2017 15:21:54 - 1.298 > +++ netinet/ip_input.c10 May 2017 23:55:42 - > @@ -130,7 +130,6 @@ void ip_ours(struct mbuf *); > int ip_dooptions(struct mbuf *, struct ifnet *); > int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **); > #ifdef IPSEC > -int ip_input_ipsec_fwd_check(struct mbuf *, int); > int ip_input_ipsec_ours_check(struct mbuf *, int); > #endif /* IPSEC */ > > @@ -241,9 +240,6 @@ ipv4_input(struct mbuf *m) > struct rtentry *rt = NULL; > struct ip *ip; > int hlen, len; > -#if defined(MROUTING) || defined(IPSEC) > - int rv; > -#endif > in_addr_t pfrdr = 0; > > ifp = if_get(m->m_pkthdr.ph_ifidx); > @@ -377,6 +373,8 @@ ipv4_input(struct mbuf *m) > > #ifdef MROUTING > if (ipmforwarding && ip_mrouter[ifp->if_rdomain]) { > + int rv; > + > if (m->m_flags & M_EXT) { > if ((m = m_pullup(m, hlen)) == NULL) { > ipstat_inc(ips_toosmall); > @@ -444,8 +442,10 @@ ipv4_input(struct mbuf *m) > } > #ifdef IPSEC > if (ipsec_in_use) { > + int rv; > + > KERNEL_LOCK(); > - rv = ip_input_ipsec_fwd_check(m, hlen); > + rv = ip_input_ipsec_fwd_check(m, hlen, AF_INET); > KERNEL_UNLOCK(); > if (rv != 0) { > ipstat_inc(ips_cantforward); > @@ -675,7 +675,7 @@ in_ouraddr(struct mbuf *m, struct ifnet > > #ifdef IPSEC > int > -ip_input_ipsec_fwd_check(struct mbuf *m, int hlen) > +ip_input_ipsec_fwd_check(struct mbuf *m, int hlen, int af) > { > struct tdb *tdb; > struct tdb_ident *tdbi; > @@ -692,8 +692,7 @@ ip_input_ipsec_fwd_check(struct mbuf *m, > tdb = gettdb(tdbi->rdomain, tdbi->spi, >dst, tdbi->proto); > } else > tdb = NULL; > - ipsp_spd_lookup(m, AF_INET, hlen, , IPSP_DIRECTION_IN, tdb, NULL, > - 0); > + ipsp_spd_lookup(m, af, hlen, , IPSP_DIRECTION_IN, tdb, NULL, 0); > > return error; > } > Index: netinet/ip_var.h > === > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_var.h,v > retrieving revision 1.71 > diff -u -p -r1.71 ip_var.h > --- netinet/ip_var.h 14 Apr 2017 20:46:31 - 1.71 > +++ netinet/ip_var.h 10 May 2017 23:12:25 - > @@ -250,6 +250,7 @@ void ip_savecontrol(struct inpcb *, str > void ipintr(void); > void ipv4_input(struct mbuf *); > void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); > +int ip_input_ipsec_fwd_check(struct mbuf *, int, int); > int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); > void rip_init(void); > int rip_input(struct mbuf **, int *, int, int); > Index: netinet6/ip6_input.c > === > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v > retrieving revision 1.184 > diff -u -p -r1.184 ip6_input.c > --- netinet6/ip6_input.c 8 May 2017 08:46:39 - 1.184 > +++ netinet6/ip6_input.c 10 May 2017 23:21:00 - > @@ -470,6 +470,24 @@ ip6_input(struct mbuf *m) > goto out; > } > > +#ifdef IPSEC > + if (ipsec_in_use) { > + int rv; > + > + KERNEL_LOCK(); > + rv = ip_input_ipsec_fwd_check(m, off, AF_INET6); > + KERNEL_UNLOCK(); > + if (rv != 0) { > + ipstat_inc(ips_cantforward); > + goto bad; > + } > + /* > + * Fall through, forward packet. Outbound IPsec policy > + * checking will occur in ip6_forward(). > + */ > + } > +#endif /* IPSEC */ > + > ip6_forward(m, rt, srcrt); > if_put(ifp); > return; >
IPsec forward policy check in ip6_input
Hi, ipv4_input() checks the IPsec policy for forwarding and local delivery. Such code is missing in IPv6, the behavior is different. Start using the forwarding check also in ip6_input(). While there avoid an ugly #ifdef in ipv4_input(). ok? bluhm Index: netinet/ip_input.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.298 diff -u -p -r1.298 ip_input.c --- netinet/ip_input.c 19 Apr 2017 15:21:54 - 1.298 +++ netinet/ip_input.c 10 May 2017 23:55:42 - @@ -130,7 +130,6 @@ voidip_ours(struct mbuf *); intip_dooptions(struct mbuf *, struct ifnet *); intin_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **); #ifdef IPSEC -intip_input_ipsec_fwd_check(struct mbuf *, int); intip_input_ipsec_ours_check(struct mbuf *, int); #endif /* IPSEC */ @@ -241,9 +240,6 @@ ipv4_input(struct mbuf *m) struct rtentry *rt = NULL; struct ip *ip; int hlen, len; -#if defined(MROUTING) || defined(IPSEC) - int rv; -#endif in_addr_t pfrdr = 0; ifp = if_get(m->m_pkthdr.ph_ifidx); @@ -377,6 +373,8 @@ ipv4_input(struct mbuf *m) #ifdef MROUTING if (ipmforwarding && ip_mrouter[ifp->if_rdomain]) { + int rv; + if (m->m_flags & M_EXT) { if ((m = m_pullup(m, hlen)) == NULL) { ipstat_inc(ips_toosmall); @@ -444,8 +442,10 @@ ipv4_input(struct mbuf *m) } #ifdef IPSEC if (ipsec_in_use) { + int rv; + KERNEL_LOCK(); - rv = ip_input_ipsec_fwd_check(m, hlen); + rv = ip_input_ipsec_fwd_check(m, hlen, AF_INET); KERNEL_UNLOCK(); if (rv != 0) { ipstat_inc(ips_cantforward); @@ -675,7 +675,7 @@ in_ouraddr(struct mbuf *m, struct ifnet #ifdef IPSEC int -ip_input_ipsec_fwd_check(struct mbuf *m, int hlen) +ip_input_ipsec_fwd_check(struct mbuf *m, int hlen, int af) { struct tdb *tdb; struct tdb_ident *tdbi; @@ -692,8 +692,7 @@ ip_input_ipsec_fwd_check(struct mbuf *m, tdb = gettdb(tdbi->rdomain, tdbi->spi, >dst, tdbi->proto); } else tdb = NULL; - ipsp_spd_lookup(m, AF_INET, hlen, , IPSP_DIRECTION_IN, tdb, NULL, - 0); + ipsp_spd_lookup(m, af, hlen, , IPSP_DIRECTION_IN, tdb, NULL, 0); return error; } Index: netinet/ip_var.h === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_var.h,v retrieving revision 1.71 diff -u -p -r1.71 ip_var.h --- netinet/ip_var.h14 Apr 2017 20:46:31 - 1.71 +++ netinet/ip_var.h10 May 2017 23:12:25 - @@ -250,6 +250,7 @@ void ip_savecontrol(struct inpcb *, str voidipintr(void); voidipv4_input(struct mbuf *); voidip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); +int ip_input_ipsec_fwd_check(struct mbuf *, int, int); int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); voidrip_init(void); int rip_input(struct mbuf **, int *, int, int); Index: netinet6/ip6_input.c === RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.184 diff -u -p -r1.184 ip6_input.c --- netinet6/ip6_input.c8 May 2017 08:46:39 - 1.184 +++ netinet6/ip6_input.c10 May 2017 23:21:00 - @@ -470,6 +470,24 @@ ip6_input(struct mbuf *m) goto out; } +#ifdef IPSEC + if (ipsec_in_use) { + int rv; + + KERNEL_LOCK(); + rv = ip_input_ipsec_fwd_check(m, off, AF_INET6); + KERNEL_UNLOCK(); + if (rv != 0) { + ipstat_inc(ips_cantforward); + goto bad; + } + /* +* Fall through, forward packet. Outbound IPsec policy +* checking will occur in ip6_forward(). +*/ + } +#endif /* IPSEC */ + ip6_forward(m, rt, srcrt); if_put(ifp); return;