On 20 Dec 2015, at 13:02, Cy Schubert wrote:

Cy Schubert writes:
In message <201511050726.ta57qxlu074...@repo.freebsd.org>, "George V.
Neville-N
eil" writes:
Author: gnn
Date: Thu Nov  5 07:26:32 2015
New Revision: 290383
URL: https://svnweb.freebsd.org/changeset/base/290383

Log:
Replace the fastforward path with tryforward which does not require a
sysctl and will always be on. The former split between default and
fast forwarding is removed by this commit while preserving the ability
to use all network stack features.

Differential Revision:  https://reviews.freebsd.org/D4042
Reviewed by:    ae, melifaro, olivier, rwatson
MFC after:      1 month
Sponsored by:   Rubicon Communications (Netgate)

Modified:
head/sys/net/if_arcsubr.c
head/sys/net/if_ethersubr.c
head/sys/net/if_fddisubr.c
head/sys/net/if_fwsubr.c
head/sys/net/if_iso88025subr.c
head/sys/netinet/in_var.h
head/sys/netinet/ip_fastfwd.c
head/sys/netinet/ip_input.c

Modified: head/sys/net/if_arcsubr.c
===========================================================================
==
=
--- head/sys/net/if_arcsubr.c   Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/net/if_arcsubr.c   Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -550,15 +550,11 @@ arc_input(struct ifnet *ifp, struct mbuf
#ifdef INET
        case ARCTYPE_IP:
                m_adj(m, ARC_HDRNEWLEN);
-               if ((m = ip_fastforward(m)) == NULL)
-                       return;
                isr = NETISR_IP;
                break;

        case ARCTYPE_IP_OLD:
                m_adj(m, ARC_HDRLEN);
-               if ((m = ip_fastforward(m)) == NULL)
-                       return;
                isr = NETISR_IP;
                break;


Modified: head/sys/net/if_ethersubr.c
===========================================================================
==
=
--- head/sys/net/if_ethersubr.c Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/net/if_ethersubr.c Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -722,8 +722,6 @@ ether_demux(struct ifnet *ifp, struct mb
        switch (ether_type) {
#ifdef INET
        case ETHERTYPE_IP:
-               if ((m = ip_fastforward(m)) == NULL)
-                       return;
                isr = NETISR_IP;
                break;


Modified: head/sys/net/if_fddisubr.c
===========================================================================
==
=
--- head/sys/net/if_fddisubr.c  Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/net/if_fddisubr.c  Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -429,8 +429,6 @@ fddi_input(ifp, m)
                switch (type) {
#ifdef INET
                case ETHERTYPE_IP:
-                       if ((m = ip_fastforward(m)) == NULL)
-                               return;
                        isr = NETISR_IP;
                        break;


Modified: head/sys/net/if_fwsubr.c
===========================================================================
==
=
--- head/sys/net/if_fwsubr.c    Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/net/if_fwsubr.c    Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -605,8 +605,6 @@ firewire_input(struct ifnet *ifp, struct
        switch (type) {
#ifdef INET
        case ETHERTYPE_IP:
-               if ((m = ip_fastforward(m)) == NULL)
-                       return;
                isr = NETISR_IP;
                break;


Modified: head/sys/net/if_iso88025subr.c
===========================================================================
==
=
--- head/sys/net/if_iso88025subr.c      Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/net/if_iso88025subr.c      Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -519,8 +519,6 @@ iso88025_input(ifp, m)
#ifdef INET
                case ETHERTYPE_IP:
                        th->iso88025_shost[0] &= ~(TR_RII);
-                       if ((m = ip_fastforward(m)) == NULL)
-                               return;
                        isr = NETISR_IP;
                        break;


Modified: head/sys/netinet/in_var.h
===========================================================================
==
=
--- head/sys/netinet/in_var.h   Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/netinet/in_var.h   Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -380,7 +380,7 @@ int in_scrubprefix(struct in_ifaddr *, u
void    ip_input(struct mbuf *);
void    ip_direct_input(struct mbuf *);
void    in_ifadown(struct ifaddr *ifa, int);
-struct mbuf    *ip_fastforward(struct mbuf *);
+struct mbuf    *ip_tryforward(struct mbuf *);
void    *in_domifattach(struct ifnet *);
void    in_domifdetach(struct ifnet *, void *);


Modified: head/sys/netinet/ip_fastfwd.c
===========================================================================
==
=
--- head/sys/netinet/ip_fastfwd.c       Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/netinet/ip_fastfwd.c       Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -108,12 +108,6 @@ __FBSDID("$FreeBSD$");

#include <machine/in_cksum.h>

-static VNET_DEFINE(int, ipfastforward_active);
-#define        V_ipfastforward_active          VNET(ipfastforward_active)
-
-SYSCTL_INT(_net_inet_ip, OID_AUTO, fastforwarding, CTLFLAG_VNET | CTLFLAG_
RW
,
- &VNET_NAME(ipfastforward_active), 0, "Enable fast IP forwarding");
-
static struct sockaddr_in *
ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
{
@@ -158,7 +152,7 @@ ip_findroute(struct route *ro, struct in
* to ip_input for full processing.
*/
struct mbuf *
-ip_fastforward(struct mbuf *m)
+ip_tryforward(struct mbuf *m)
{
        struct ip *ip;
        struct mbuf *m0 = NULL;
@@ -166,119 +160,20 @@ ip_fastforward(struct mbuf *m)
        struct sockaddr_in *dst = NULL;
        struct ifnet *ifp;
        struct in_addr odest, dest;
-       uint16_t sum, ip_len, ip_off;
+       uint16_t ip_len, ip_off;
        int error = 0;
-       int hlen, mtu;
+       int mtu;
        struct m_tag *fwd_tag = NULL;

        /*
         * Are we active and forwarding packets?
         */
-       if (!V_ipfastforward_active || !V_ipforwarding)
-               return m;

        M_ASSERTVALID(m);
        M_ASSERTPKTHDR(m);

        bzero(&ro, sizeof(ro));

-       /*
-        * Step 1: check for packet drop conditions (and sanity checks)
-        */
-
-       /*
-        * Is entire packet big enough?
-        */
-       if (m->m_pkthdr.len < sizeof(struct ip)) {
-               IPSTAT_INC(ips_tooshort);
-               goto drop;
-       }
-
-       /*
-        * Is first mbuf large enough for ip header and is header present?
-        */
-       if (m->m_len < sizeof (struct ip) &&
-          (m = m_pullup(m, sizeof (struct ip))) == NULL) {
-               IPSTAT_INC(ips_toosmall);
-               return NULL;    /* mbuf already free'd */
-       }
-
-       ip = mtod(m, struct ip *);
-
-       /*
-        * Is it IPv4?
-        */
-       if (ip->ip_v != IPVERSION) {
-               IPSTAT_INC(ips_badvers);
-               goto drop;
-       }
-
-       /*
-        * Is IP header length correct and is it in first mbuf?
-        */
-       hlen = ip->ip_hl << 2;
-       if (hlen < sizeof(struct ip)) {      /* minimum header length */
-               IPSTAT_INC(ips_badhlen);
-               goto drop;
-       }
-       if (hlen > m->m_len) {
-               if ((m = m_pullup(m, hlen)) == NULL) {
-                       IPSTAT_INC(ips_badhlen);
-                       return NULL;    /* mbuf already free'd */
-               }
-               ip = mtod(m, struct ip *);
-       }
-
-       /*
-        * Checksum correct?
-        */
-       if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED)
-               sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID);
-       else {
-               if (hlen == sizeof(struct ip))
-                       sum = in_cksum_hdr(ip);
-               else
-                       sum = in_cksum(m, hlen);
-       }
-       if (sum) {
-               IPSTAT_INC(ips_badsum);
-               goto drop;
-       }
-
-       /*
-        * Remember that we have checked the IP header and found it valid.
-        */
-       m->m_pkthdr.csum_flags |= (CSUM_IP_CHECKED | CSUM_IP_VALID);
-
-       ip_len = ntohs(ip->ip_len);
-
-       /*
-        * Is IP length longer than packet we have got?
-        */
-       if (m->m_pkthdr.len < ip_len) {
-               IPSTAT_INC(ips_tooshort);
-               goto drop;
-       }
-
-       /*
- * Is packet longer than IP header tells us? If yes, truncate packet.
-        */
-       if (m->m_pkthdr.len > ip_len) {
-               if (m->m_len == m->m_pkthdr.len) {
-                       m->m_len = ip_len;
-                       m->m_pkthdr.len = ip_len;
-               } else
-                       m_adj(m, ip_len - m->m_pkthdr.len);
-       }
-
-       /*
-        * Is packet from or to 127/8?
-        */
- if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || - (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
-               IPSTAT_INC(ips_badaddr);
-               goto drop;
-       }

#ifdef ALTQ
        /*
@@ -289,12 +184,10 @@ ip_fastforward(struct mbuf *m)
#endif

        /*
-        * Step 2: fallback conditions to normal ip_input path processing
-        */
-
-       /*
         * Only IP packets without options
         */
+       ip = mtod(m, struct ip *);
+
        if (ip->ip_hl != (sizeof(struct ip) >> 2)) {
                if (V_ip_doopts == 1)
                        return m;

Modified: head/sys/netinet/ip_input.c
===========================================================================
==
=
--- head/sys/netinet/ip_input.c Thu Nov  5 04:16:03 2015        (r29038
2)
+++ head/sys/netinet/ip_input.c Thu Nov  5 07:26:32 2015        (r29038
3)
@@ -79,6 +79,8 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip_carp.h>
#ifdef IPSEC
#include <netinet/ip_ipsec.h>
+#include <netipsec/ipsec.h>
+#include <netipsec/key.h>
#endif /* IPSEC */
#include <netinet/in_rss.h>

@@ -500,12 +502,22 @@ tooshort:
                        m_adj(m, ip_len - m->m_pkthdr.len);
        }

+       /* Try to forward the packet, but if we fail continue */
#ifdef IPSEC
+       /* For now we do not handle IPSEC in tryforward. */
+ if (!key_havesp(IPSEC_DIR_INBOUND) && !key_havesp(IPSEC_DIR_OUTBOUND) &
&
+           (V_ipforwarding == 1))
+               if (ip_tryforward(m) == NULL)
+                       return;
        /*
         * Bypass packet filtering for packets previously handled by IPsec.
         */
        if (ip_ipsec_filtertunnel(m))
                goto passin;
+#else
+       if (V_ipforwarding == 1)
+               if (ip_tryforward(m) == NULL)
+                       return;
#endif /* IPSEC */

        /*



Hi George,

Sorry for the lateness of this reply, I finally got some time off for
Christmas and have time to myself to boot.

This breaks ipfilter's ipnat. I want to let you know before anyone MFCs
this.

A fix to ipfilter has been committed to head and will be MFCed in a week.


Let me know when that's done.

Thanks!

Best,
George
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to