Re: [libvirt] [libvirt PATCHv5 2/2] add leasefile support
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
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 =