ipflow: Flush ipflow if a new route is successfully added.
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 28 Mar 2009 03:02:45 +0000 (11:02 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sat, 28 Mar 2009 04:28:47 +0000 (12:28 +0800)
ipflow suffers same problem as described in FreeBSD-PR: kern/10778
Though the time of mis-routing will not be "arbitrarily long time"
for intermittent packet flow (thanks to the ipflow timeout), it
still could be quite long for a constant packet flow.

sys/netinet/in_rmx.c
sys/netinet/ip_flow.c
sys/netinet/ip_flow.h

index 6fc1559..9fb755c 100644 (file)
@@ -58,6 +58,7 @@
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_var.h>
+#include <netinet/ip_flow.h>
 
 #define RTPRF_EXPIRING RTF_PROTO3      /* set on routes we manage */
 
@@ -136,6 +137,17 @@ in_addroute(char *key, char *mask, struct radix_node_head *head,
                        }
                }
        }
+
+       /*
+        * If the new route has been created successfully, and it is
+        * not a multicast/broadcast or cloned route, then we will
+        * have to flush the ipflow.  Otherwise, we may end up using
+        * the wrong route.
+        */
+       if (ret != NULL &&
+           (rt->rt_flags &
+            (RTF_MULTICAST | RTF_BROADCAST | RTF_WASCLONED)) == 0)
+               ipflow_flush_oncpu();
        return ret;
 }
 
index 3872761..5792aea 100644 (file)
@@ -499,6 +499,17 @@ ipflow_create(const struct route *ro, struct mbuf *m)
        IPFLOW_INSERT(&ipflowtable[hash], ipf);
 }
 
+void
+ipflow_flush_oncpu(void)
+{
+       struct ipflow *ipf;
+
+       while ((ipf = LIST_FIRST(&ipflowlist)) != NULL) {
+               IPFLOW_REMOVE(ipf);
+               IPFLOW_FREE(ipf);
+       }
+}
+
 static void
 ipflow_init(void)
 {
index a5a7698..c67e738 100644 (file)
@@ -48,6 +48,7 @@ struct route;
 int    ipflow_fastforward(struct mbuf *);
 void   ipflow_create(const struct route *, struct mbuf *);
 void   ipflow_slowtimo(void);
+void   ipflow_flush_oncpu(void);
 
 #endif /* _KERNEL */