Re: IPsec forward policy check in ip6_input

2017-05-11 Thread Alexander Bluhm
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

2017-05-11 Thread Mike Belopuhov
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

2017-05-11 Thread Alexander Bluhm
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;