Re: [libvirt] [libvirt PATCHv5 2/2] add leasefile support

2011-11-16 Thread Stefan Berger

On 11/10/2011 03:28 PM, David L Stevens wrote:

This patch adds support for saving DHCP snooping leases to an on-disk
file and restoring saved leases that are still active on restart.

Signed-off-by: David L Stevensdlstev...@us.ibm.com
---
  src/nwfilter/nwfilter_dhcpsnoop.c |  270 +
  1 files changed, 243 insertions(+), 27 deletions(-)

diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c 
b/src/nwfilter/nwfilter_dhcpsnoop.c
index 8a37a6f..918ad7b 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -55,10 +55,18 @@
  #include nwfilter_gentech_driver.h
  #include nwfilter_ebiptables_driver.h
  #include nwfilter_dhcpsnoop.h
+#include virfile.h
+#include configmake.h

  #define VIR_FROM_THIS VIR_FROM_NWFILTER

  #ifdef HAVE_LIBPCAP
+
+#define LEASEFILE LOCALSTATEDIR /run/libvirt/network/nwfilter.leases
+#define TMPLEASEFILE LOCALSTATEDIR /run/libvirt/network/nwfilter.ltmp
+static int lease_fd = -1;
+static int nleases = 0; /* number of active leases */
+static int wleases = 0; /* number of written leases */

  static virHashTablePtr SnoopReqs;
  static pthread_mutex_t SnoopLock;
@@ -76,6 +84,7 @@ struct virNWFilterSnoopReq {
  const char   *filtername;
  virNWFilterHashTablePtr   vars;
  virNWFilterDriverStatePtr driver;
+bool  running;
  /* start and end of lease list, ordered by lease time */
  struct iplease   *start;
  struct iplease   *end;
@@ -96,7 +105,15 @@ struct iplease {

  static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr);
  static void ipl_update(struct iplease *pl, uint32_t timeout);
+
+static struct virNWFilterSnoopReq *newreq(const char *ifname);

+static void lease_open(void);
+static void lease_close(void);
+static void lease_load(void);
+static void lease_save(struct iplease *ipl);
+static void lease_restore(struct virNWFilterSnoopReq *req);
+static void lease_refresh(void);

  /*
   * ipl_ladd - add an IP lease to a list
@@ -187,7 +204,7 @@ ipl_install(struct iplease *ipl)
   * ipl_add - create or update an IP lease
   */
  static void
-ipl_add(struct iplease *plnew)
+ipl_add(struct iplease *plnew, bool update_leasefile)
  {
  struct iplease *pl;
  struct virNWFilterSnoopReq *req = plnew-ipl_req;
@@ -195,6 +212,8 @@ ipl_add(struct iplease *plnew)
  pl = ipl_getbyip(req-start, plnew-ipl_ipaddr);
  if (pl) {
  ipl_update(pl, plnew-ipl_timeout);
+if (update_leasefile)
+lease_save(pl);
  return;
  }
  /* support for multiple addresses requires the ability to add filters
@@ -212,11 +231,14 @@ ipl_add(struct iplease *plnew)
  }
  *pl = *plnew;

-if (ipl_install(pl)  0) {
+if (req-running  ipl_install(pl)  0) {
  VIR_FREE(pl);
  return;
  }
  ipl_tadd(pl);
+nleases++;
+if (update_leasefile)
+lease_save(pl);
  }

  /*
@@ -252,7 +274,7 @@ ipl_tdel(struct iplease *ipl)
   * ipl_del - delete an IP lease
   */
  static void
-ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr)
+ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr, bool 
update_leasefile)
  {
  struct iplease *ipl;

@@ -262,13 +284,18 @@ ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr)

  ipl_tdel(ipl);

-/* for multiple address support, this needs to remove those rules
- * referencing IP with ipl's ip value.
- */
-if (req-techdriver-applyDHCPOnlyRules(req-ifname, req-macaddr, NULL)) {
-virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, ipl_ldel failed);
+if (update_leasefile) {
+lease_save(ipl);
+
+/*
+ * for multiple address support, this needs to remove those rules
+ * referencing IP with ipl's ip value.
+ */
+if (req-techdriver-applyDHCPOnlyRules(req-ifname,req-macaddr,NULL))
+virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, ipl_ldel failed);
  }
  VIR_FREE(ipl);
+nleases--;
  }

  /*
@@ -308,7 +335,7 @@ ipl_trun(struct virNWFilterSnoopReq *req)

  now = time(0);
  while (req-start  req-start-ipl_timeout= now)
-ipl_del(req, req-start-ipl_ipaddr);
+ipl_del(req, req-start-ipl_ipaddr, 1);
  return 0;
  }

@@ -467,11 +494,11 @@ dhcpdecode(struct virNWFilterSnoopReq *req, struct eth 
*pep, int len)

  switch (mtype) {
  case DHCPACK:
-ipl_add(ipl);
+ipl_add(ipl, 1);
  break;
  case DHCPDECLINE:
  case DHCPRELEASE:
-ipl_del(req, ipl.ipl_ipaddr);
+ipl_del(req, ipl.ipl_ipaddr, 1);
  break;
  default:
  break;
@@ -521,7 +548,7 @@ snoopReqFree(struct virNWFilterSnoopReq *req)
  /* free all leases */
  snoop_lock();
  for (ipl = req-start; ipl; ipl = req-start)
-ipl_del(req, ipl-ipl_ipaddr);
+ipl_del(req, ipl-ipl_ipaddr, 0);
  snoop_unlock();

  /* free 

[libvirt] [libvirt PATCHv5 2/2] add leasefile support

2011-11-10 Thread David L Stevens
This patch adds support for saving DHCP snooping leases to an on-disk
file and restoring saved leases that are still active on restart.

Signed-off-by: David L Stevens dlstev...@us.ibm.com
---
 src/nwfilter/nwfilter_dhcpsnoop.c |  270 +
 1 files changed, 243 insertions(+), 27 deletions(-)

diff --git a/src/nwfilter/nwfilter_dhcpsnoop.c 
b/src/nwfilter/nwfilter_dhcpsnoop.c
index 8a37a6f..918ad7b 100644
--- a/src/nwfilter/nwfilter_dhcpsnoop.c
+++ b/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -55,10 +55,18 @@
 #include nwfilter_gentech_driver.h
 #include nwfilter_ebiptables_driver.h
 #include nwfilter_dhcpsnoop.h
+#include virfile.h
+#include configmake.h
 
 #define VIR_FROM_THIS VIR_FROM_NWFILTER
 
 #ifdef HAVE_LIBPCAP
+ 
+#define LEASEFILE LOCALSTATEDIR /run/libvirt/network/nwfilter.leases
+#define TMPLEASEFILE LOCALSTATEDIR /run/libvirt/network/nwfilter.ltmp
+static int lease_fd = -1;
+static int nleases = 0; /* number of active leases */
+static int wleases = 0; /* number of written leases */
 
 static virHashTablePtr SnoopReqs;
 static pthread_mutex_t SnoopLock;
@@ -76,6 +84,7 @@ struct virNWFilterSnoopReq {
 const char   *filtername;
 virNWFilterHashTablePtr   vars;
 virNWFilterDriverStatePtr driver;
+bool  running;
 /* start and end of lease list, ordered by lease time */
 struct iplease   *start;
 struct iplease   *end;
@@ -96,7 +105,15 @@ struct iplease {
 
 static struct iplease *ipl_getbyip(struct iplease *start, uint32_t ipaddr);
 static void ipl_update(struct iplease *pl, uint32_t timeout);
+ 
+static struct virNWFilterSnoopReq *newreq(const char *ifname);
 
+static void lease_open(void);
+static void lease_close(void);
+static void lease_load(void);
+static void lease_save(struct iplease *ipl);
+static void lease_restore(struct virNWFilterSnoopReq *req);
+static void lease_refresh(void);
 
 /*
  * ipl_ladd - add an IP lease to a list
@@ -187,7 +204,7 @@ ipl_install(struct iplease *ipl)
  * ipl_add - create or update an IP lease
  */
 static void
-ipl_add(struct iplease *plnew)
+ipl_add(struct iplease *plnew, bool update_leasefile)
 {
 struct iplease *pl;
 struct virNWFilterSnoopReq *req = plnew-ipl_req;
@@ -195,6 +212,8 @@ ipl_add(struct iplease *plnew)
 pl = ipl_getbyip(req-start, plnew-ipl_ipaddr);
 if (pl) {
 ipl_update(pl, plnew-ipl_timeout);
+if (update_leasefile)
+lease_save(pl);
 return;
 }
 /* support for multiple addresses requires the ability to add filters
@@ -212,11 +231,14 @@ ipl_add(struct iplease *plnew)
 }
 *pl = *plnew;
 
-if (ipl_install(pl)  0) {
+if (req-running  ipl_install(pl)  0) {
 VIR_FREE(pl);
 return;
 }
 ipl_tadd(pl);
+nleases++;
+if (update_leasefile)
+lease_save(pl);
 }
 
 /*
@@ -252,7 +274,7 @@ ipl_tdel(struct iplease *ipl)
  * ipl_del - delete an IP lease
  */
 static void
-ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr)
+ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr, bool 
update_leasefile)
 {
 struct iplease *ipl;
 
@@ -262,13 +284,18 @@ ipl_del(struct virNWFilterSnoopReq *req, uint32_t ipaddr)
 
 ipl_tdel(ipl);
 
-/* for multiple address support, this needs to remove those rules
- * referencing IP with ipl's ip value.
- */
-if (req-techdriver-applyDHCPOnlyRules(req-ifname, req-macaddr, NULL)) {
-virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, ipl_ldel failed);
+if (update_leasefile) {
+lease_save(ipl);
+
+/*
+ * for multiple address support, this needs to remove those rules
+ * referencing IP with ipl's ip value.
+ */
+if (req-techdriver-applyDHCPOnlyRules(req-ifname,req-macaddr,NULL))
+virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, ipl_ldel failed);
 }
 VIR_FREE(ipl);
+nleases--;
 }
 
 /*
@@ -308,7 +335,7 @@ ipl_trun(struct virNWFilterSnoopReq *req)
 
 now = time(0);
 while (req-start  req-start-ipl_timeout = now)
-ipl_del(req, req-start-ipl_ipaddr);
+ipl_del(req, req-start-ipl_ipaddr, 1);
 return 0;
 }
 
@@ -467,11 +494,11 @@ dhcpdecode(struct virNWFilterSnoopReq *req, struct eth 
*pep, int len)
 
 switch (mtype) {
 case DHCPACK:
-ipl_add(ipl);
+ipl_add(ipl, 1);
 break;
 case DHCPDECLINE:
 case DHCPRELEASE:
-ipl_del(req, ipl.ipl_ipaddr);
+ipl_del(req, ipl.ipl_ipaddr, 1);
 break;
 default:
 break;
@@ -521,7 +548,7 @@ snoopReqFree(struct virNWFilterSnoopReq *req)
 /* free all leases */
 snoop_lock();
 for (ipl = req-start; ipl; ipl = req-start)
-ipl_del(req, ipl-ipl_ipaddr);
+ipl_del(req, ipl-ipl_ipaddr, 0);
 snoop_unlock();
 
 /* free all req data */
@@ -547,6 +574,8 @@ virNWFilterDHCPSnoop(void *req0)
 
 ifindex =