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;
>