Dumping IPsec flows w/ radix-tree

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Dumping IPsec flows w/ radix-tree

Martin Pieuchot
Diff below switches the logic of the NET_KEY_SPD_DUMP sysctl(2) to
iterate over the SPD table instead of the global list of policies
`ipsec_policy_head'.

This will allow us to get rid of the global list, which makes future
MP work easier.

Since we're now iterating over a tree, this diff changes the output
of ipsecctl(8) a bit.  But I'd say it's a feature, it allows us to
see how flows are ordered, which is useful for debugging ;)
It is also useful to compare configurations since you can now diff
the output in order to figure if some flow are missing.


Before
 flow esp in from 192.168.200.0/24 to 10.10.10.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp out from 10.10.10.0/24 to 192.168.200.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp in from 192.168.200.0/24 to 10.10.11.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp out from 10.10.11.0/24 to 192.168.200.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp in from 192.168.100.0/24 to 10.10.10.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp out from 10.10.10.0/24 to 192.168.100.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp in from 192.168.100.0/24 to 10.10.11.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp out from 10.10.11.0/24 to 192.168.100.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require


After:
 flow esp in from 192.168.100.0/24 to 10.10.10.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp in from 192.168.100.0/24 to 10.10.11.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp in from 192.168.200.0/24 to 10.10.10.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp in from 192.168.200.0/24 to 10.10.11.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type use
 flow esp out from 10.10.10.0/24 to 192.168.100.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp out from 10.10.10.0/24 to 192.168.200.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp out from 10.10.11.0/24 to 192.168.100.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require
 flow esp out from 10.10.11.0/24 to 192.168.200.0/24 peer 192.168.1.80 srcid 192.168.1.102/32 dstid 192.168.1.80/32 type require


ok?


Index: net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.168
diff -u -p -r1.168 pfkeyv2.c
--- net/pfkeyv2.c 16 Oct 2017 08:22:25 -0000 1.168
+++ net/pfkeyv2.c 24 Oct 2017 13:31:56 -0000
@@ -165,6 +165,7 @@ int pfkeyv2_usrreq(struct socket *, int,
 int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *,
     struct mbuf *);
 int pfkey_sendup(struct keycb *, struct mbuf *, int);
+int pfkeyv2_sysctl_policydumper(struct ipsec_policy *, void *, unsigned int);
 
 /*
  * Wrapper around m_devget(); copy data from contiguous buffer to mbuf
@@ -2324,24 +2325,8 @@ ret:
 }
 
 int
-pfkeyv2_ipo_walk(u_int rdomain, int (*walker)(struct ipsec_policy *, void *),
-    void *arg)
-{
- int rval = 0;
- struct ipsec_policy *ipo;
-
- NET_ASSERT_LOCKED();
-
- TAILQ_FOREACH(ipo, &ipsec_policy_head, ipo_list) {
- if (ipo->ipo_rdomain != rdomain)
- continue;
- rval = walker(ipo, (void *)arg);
- }
- return (rval);
-}
-
-int
-pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg)
+pfkeyv2_sysctl_policydumper(struct ipsec_policy *ipo, void *arg,
+    unsigned int tableid)
 {
  struct pfkeyv2_sysctl_walk *w = (struct pfkeyv2_sysctl_walk *)arg;
  void *buffer = 0;
@@ -2433,7 +2418,7 @@ pfkeyv2_sysctl(int *name, u_int namelen,
 
  case NET_KEY_SPD_DUMP:
  NET_LOCK();
- error = pfkeyv2_ipo_walk(rdomain,
+ error = spd_table_walk(rdomain,
     pfkeyv2_sysctl_policydumper, &w);
  NET_UNLOCK();
  if (oldp)
Index: net/pfkeyv2.h
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.h,v
retrieving revision 1.77
diff -u -p -r1.77 pfkeyv2.h
--- net/pfkeyv2.h 29 May 2017 14:28:01 -0000 1.77
+++ net/pfkeyv2.h 24 Oct 2017 13:32:06 -0000
@@ -382,9 +382,7 @@ int pfkeyv2_flush_walker(struct tdb *, v
 int pfkeyv2_get_proto_alg(u_int8_t, u_int8_t *, int *);
 int pfkeyv2_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 int pfkeyv2_sysctl_walker(struct tdb *, void *, int);
-int pfkeyv2_ipo_walk(u_int, int (*)(struct ipsec_policy *, void *), void *);
 int pfkeyv2_sysctl_dump(void *);
-int pfkeyv2_sysctl_policydumper(struct ipsec_policy *, void *);
 
 int pfdatatopacket(void *, int, struct mbuf **);
 
Index: netinet/ip_ipsp.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_ipsp.h,v
retrieving revision 1.184
diff -u -p -r1.184 ip_ipsp.h
--- netinet/ip_ipsp.h 16 Oct 2017 08:22:25 -0000 1.184
+++ netinet/ip_ipsp.h 24 Oct 2017 13:22:39 -0000
@@ -449,6 +449,8 @@ const char *ipsp_address(union sockaddr_
 /* SPD tables */
 struct radix_node_head *spd_table_add(unsigned int);
 struct radix_node_head *spd_table_get(unsigned int);
+int spd_table_walk(unsigned int,
+    int (*walker)(struct ipsec_policy *, void *, unsigned int), void *);
 
 /* TDB management routines */
 uint32_t reserve_spi(u_int, u_int32_t, u_int32_t, union sockaddr_union *,
Index: netinet/ip_spd.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_spd.c,v
retrieving revision 1.93
diff -u -p -r1.93 ip_spd.c
--- netinet/ip_spd.c 16 Oct 2017 08:22:25 -0000 1.93
+++ netinet/ip_spd.c 24 Oct 2017 13:21:19 -0000
@@ -115,6 +115,20 @@ spd_table_add(unsigned int rtableid)
  return (spd_tables[rdomain]);
 }
 
+int
+spd_table_walk(unsigned int rtableid,
+    int (*walker)(struct ipsec_policy *, void *, unsigned int), void *arg)
+{
+ struct radix_node_head *rnh;
+
+ rnh = spd_table_get(rtableid);
+ if (rnh == NULL)
+ return (0);
+
+ return (rn_walktree(rnh,
+    (int (*)(struct radix_node *, void *, u_int))walker, arg));
+}
+
 /*
  * Lookup at the SPD based on the headers contained on the mbuf. The second
  * argument indicates what protocol family the header at the beginning of

Reply | Threaded
Open this post in threaded view
|

Re: Dumping IPsec flows w/ radix-tree

Todd C. Miller
On Tue, 24 Oct 2017 15:46:43 +0200, Martin Pieuchot wrote:

> Since we're now iterating over a tree, this diff changes the output
> of ipsecctl(8) a bit.  But I'd say it's a feature, it allows us to
> see how flows are ordered, which is useful for debugging ;)
> It is also useful to compare configurations since you can now diff
> the output in order to figure if some flow are missing.

This seems like an improvement so OK millert@.

 - todd