1 /*
2  * libvirt-nwfilter.c: entry points for virNwfilterPtr APIs
3  *
4  * Copyright (C) 2006-2015 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "datatypes.h"
24 #include "virlog.h"
25 
26 VIR_LOG_INIT("libvirt.nwfilter");
27 
28 #define VIR_FROM_THIS VIR_FROM_NWFILTER
29 
30 
31 /**
32  * virConnectNumOfNWFilters:
33  * @conn: pointer to the hypervisor connection
34  *
35  * Provides the number of nwfilters.
36  *
37  * Returns the number of nwfilters found or -1 in case of error
38  */
39 int
virConnectNumOfNWFilters(virConnectPtr conn)40 virConnectNumOfNWFilters(virConnectPtr conn)
41 {
42     VIR_DEBUG("conn=%p", conn);
43 
44     virResetLastError();
45 
46     virCheckConnectReturn(conn, -1);
47 
48     if (conn->nwfilterDriver && conn->nwfilterDriver->connectNumOfNWFilters) {
49         int ret;
50         ret = conn->nwfilterDriver->connectNumOfNWFilters(conn);
51         if (ret < 0)
52             goto error;
53         return ret;
54     }
55 
56     virReportUnsupportedError();
57 
58  error:
59     virDispatchError(conn);
60     return -1;
61 }
62 
63 
64 /**
65  * virConnectListAllNWFilters:
66  * @conn: Pointer to the hypervisor connection.
67  * @filters: Pointer to a variable to store the array containing the network
68  *           filter objects or NULL if the list is not required (just returns
69  *           number of network filters).
70  * @flags: extra flags; not used yet, so callers should always pass 0
71  *
72  * Collect the list of network filters, and allocate an array to store those
73  * objects.
74  *
75  * Returns the number of network filters found or -1 and sets @filters to  NULL
76  * in case of error.  On success, the array stored into @filters is guaranteed to
77  * have an extra allocated element set to NULL but not included in the return count,
78  * to make iteration easier.  The caller is responsible for calling
79  * virNWFilterFree() on each array element, then calling free() on @filters.
80  */
81 int
virConnectListAllNWFilters(virConnectPtr conn,virNWFilterPtr ** filters,unsigned int flags)82 virConnectListAllNWFilters(virConnectPtr conn,
83                            virNWFilterPtr **filters,
84                            unsigned int flags)
85 {
86     VIR_DEBUG("conn=%p, filters=%p, flags=0x%x", conn, filters, flags);
87 
88     virResetLastError();
89 
90     if (filters)
91         *filters = NULL;
92 
93     virCheckConnectReturn(conn, -1);
94 
95     if (conn->nwfilterDriver &&
96         conn->nwfilterDriver->connectListAllNWFilters) {
97         int ret;
98         ret = conn->nwfilterDriver->connectListAllNWFilters(conn, filters, flags);
99         if (ret < 0)
100             goto error;
101         return ret;
102     }
103 
104     virReportUnsupportedError();
105 
106  error:
107     virDispatchError(conn);
108     return -1;
109 }
110 
111 
112 /**
113  * virConnectListNWFilters:
114  * @conn: pointer to the hypervisor connection
115  * @names: array to collect the list of names of network filters
116  * @maxnames: size of @names
117  *
118  * Collect the list of network filters, and store their names in @names
119  *
120  * The use of this function is discouraged. Instead, use
121  * virConnectListAllNWFilters().
122  *
123  * Returns the number of network filters found or -1 in case of error
124  */
125 int
virConnectListNWFilters(virConnectPtr conn,char ** const names,int maxnames)126 virConnectListNWFilters(virConnectPtr conn, char **const names, int maxnames)
127 {
128     VIR_DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames);
129 
130     virResetLastError();
131 
132     virCheckConnectReturn(conn, -1);
133     virCheckNonNullArrayArgGoto(names, maxnames, error);
134     virCheckNonNegativeArgGoto(maxnames, error);
135 
136     if (conn->nwfilterDriver && conn->nwfilterDriver->connectListNWFilters) {
137         int ret;
138         ret = conn->nwfilterDriver->connectListNWFilters(conn, names, maxnames);
139         if (ret < 0)
140             goto error;
141         return ret;
142     }
143 
144     virReportUnsupportedError();
145 
146  error:
147     virDispatchError(conn);
148     return -1;
149 }
150 
151 
152 /**
153  * virNWFilterLookupByName:
154  * @conn: pointer to the hypervisor connection
155  * @name: name for the network filter
156  *
157  * Try to lookup a network filter on the given hypervisor based on its name.
158  *
159  * virNWFilterFree should be used to free the resources after the
160  * nwfilter object is no longer needed.
161  *
162  * Returns a new nwfilter object or NULL in case of failure.  If the
163  * network filter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
164  */
165 virNWFilterPtr
virNWFilterLookupByName(virConnectPtr conn,const char * name)166 virNWFilterLookupByName(virConnectPtr conn, const char *name)
167 {
168     VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(name));
169 
170     virResetLastError();
171 
172     virCheckConnectReturn(conn, NULL);
173     virCheckNonNullArgGoto(name, error);
174 
175     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByName) {
176         virNWFilterPtr ret;
177         ret = conn->nwfilterDriver->nwfilterLookupByName(conn, name);
178         if (!ret)
179             goto error;
180         return ret;
181     }
182 
183     virReportUnsupportedError();
184 
185  error:
186     virDispatchError(conn);
187     return NULL;
188 }
189 
190 
191 /**
192  * virNWFilterLookupByUUID:
193  * @conn: pointer to the hypervisor connection
194  * @uuid: the raw UUID for the network filter
195  *
196  * Try to lookup a network filter on the given hypervisor based on its UUID.
197  *
198  * virNWFilterFree should be used to free the resources after the
199  * nwfilter object is no longer needed.
200  *
201  * Returns a new nwfilter object or NULL in case of failure.  If the
202  * nwfdilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
203  */
204 virNWFilterPtr
virNWFilterLookupByUUID(virConnectPtr conn,const unsigned char * uuid)205 virNWFilterLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
206 {
207     VIR_UUID_DEBUG(conn, uuid);
208 
209     virResetLastError();
210 
211     virCheckConnectReturn(conn, NULL);
212     virCheckNonNullArgGoto(uuid, error);
213 
214     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterLookupByUUID) {
215         virNWFilterPtr ret;
216         ret = conn->nwfilterDriver->nwfilterLookupByUUID(conn, uuid);
217         if (!ret)
218             goto error;
219         return ret;
220     }
221 
222     virReportUnsupportedError();
223 
224  error:
225     virDispatchError(conn);
226     return NULL;
227 }
228 
229 
230 /**
231  * virNWFilterLookupByUUIDString:
232  * @conn: pointer to the hypervisor connection
233  * @uuidstr: the string UUID for the nwfilter
234  *
235  * Try to lookup an nwfilter on the given hypervisor based on its UUID.
236  *
237  * virNWFilterFree should be used to free the resources after the
238  * nwfilter object is no longer needed.
239  *
240  * Returns a new nwfilter object or NULL in case of failure.  If the
241  * nwfilter cannot be found, then VIR_ERR_NO_NWFILTER error is raised.
242  */
243 virNWFilterPtr
virNWFilterLookupByUUIDString(virConnectPtr conn,const char * uuidstr)244 virNWFilterLookupByUUIDString(virConnectPtr conn, const char *uuidstr)
245 {
246     unsigned char uuid[VIR_UUID_BUFLEN];
247     VIR_DEBUG("conn=%p, uuidstr=%s", conn, NULLSTR(uuidstr));
248 
249     virResetLastError();
250 
251     virCheckConnectReturn(conn, NULL);
252     virCheckNonNullArgGoto(uuidstr, error);
253 
254     if (virUUIDParse(uuidstr, uuid) < 0) {
255         virReportInvalidArg(uuidstr,
256                             _("uuidstr in %s must be a valid UUID"),
257                             __FUNCTION__);
258         goto error;
259     }
260 
261     return virNWFilterLookupByUUID(conn, &uuid[0]);
262 
263  error:
264     virDispatchError(conn);
265     return NULL;
266 }
267 
268 
269 /**
270  * virNWFilterFree:
271  * @nwfilter: a nwfilter object
272  *
273  * Free the nwfilter object. The running instance is kept alive.
274  * The data structure is freed and should not be used thereafter.
275  *
276  * Returns 0 in case of success and -1 in case of failure.
277  */
278 int
virNWFilterFree(virNWFilterPtr nwfilter)279 virNWFilterFree(virNWFilterPtr nwfilter)
280 {
281     VIR_DEBUG("nwfilter=%p", nwfilter);
282 
283     virResetLastError();
284 
285     virCheckNWFilterReturn(nwfilter, -1);
286 
287     virObjectUnref(nwfilter);
288     return 0;
289 }
290 
291 
292 /**
293  * virNWFilterGetName:
294  * @nwfilter: a nwfilter object
295  *
296  * Get the public name for the network filter
297  *
298  * Returns a pointer to the name or NULL, the string need not be deallocated
299  * its lifetime will be the same as the nwfilter object.
300  */
301 const char *
virNWFilterGetName(virNWFilterPtr nwfilter)302 virNWFilterGetName(virNWFilterPtr nwfilter)
303 {
304     VIR_DEBUG("nwfilter=%p", nwfilter);
305 
306     virResetLastError();
307 
308     virCheckNWFilterReturn(nwfilter, NULL);
309 
310     return nwfilter->name;
311 }
312 
313 
314 /**
315  * virNWFilterGetUUID:
316  * @nwfilter: a nwfilter object
317  * @uuid: pointer to a VIR_UUID_BUFLEN bytes array
318  *
319  * Get the UUID for a network filter
320  *
321  * Returns -1 in case of error, 0 in case of success
322  */
323 int
virNWFilterGetUUID(virNWFilterPtr nwfilter,unsigned char * uuid)324 virNWFilterGetUUID(virNWFilterPtr nwfilter, unsigned char *uuid)
325 {
326     VIR_DEBUG("nwfilter=%p, uuid=%p", nwfilter, uuid);
327 
328     virResetLastError();
329 
330     virCheckNWFilterReturn(nwfilter, -1);
331     virCheckNonNullArgGoto(uuid, error);
332 
333     memcpy(uuid, &nwfilter->uuid[0], VIR_UUID_BUFLEN);
334 
335     return 0;
336 
337  error:
338     virDispatchError(nwfilter->conn);
339     return -1;
340 }
341 
342 
343 /**
344  * virNWFilterGetUUIDString:
345  * @nwfilter: a nwfilter object
346  * @buf: pointer to a VIR_UUID_STRING_BUFLEN bytes array
347  *
348  * Get the UUID for a network filter as string. For more information about
349  * UUID see RFC4122.
350  *
351  * Returns -1 in case of error, 0 in case of success
352  */
353 int
virNWFilterGetUUIDString(virNWFilterPtr nwfilter,char * buf)354 virNWFilterGetUUIDString(virNWFilterPtr nwfilter, char *buf)
355 {
356     VIR_DEBUG("nwfilter=%p, buf=%p", nwfilter, buf);
357 
358     virResetLastError();
359 
360     virCheckNWFilterReturn(nwfilter, -1);
361     virCheckNonNullArgGoto(buf, error);
362 
363     virUUIDFormat(nwfilter->uuid, buf);
364     return 0;
365 
366  error:
367     virDispatchError(nwfilter->conn);
368     return -1;
369 }
370 
371 
372 /**
373  * virNWFilterDefineXML:
374  * @conn: pointer to the hypervisor connection
375  * @xmlDesc: an XML description of the nwfilter
376  *
377  * Define a new network filter, based on an XML description
378  * similar to the one returned by virNWFilterGetXMLDesc()
379  *
380  * virNWFilterFree should be used to free the resources after the
381  * nwfilter object is no longer needed.
382  *
383  * Returns a new nwfilter object or NULL in case of failure
384  */
385 virNWFilterPtr
virNWFilterDefineXML(virConnectPtr conn,const char * xmlDesc)386 virNWFilterDefineXML(virConnectPtr conn, const char *xmlDesc)
387 {
388     VIR_DEBUG("conn=%p, xmlDesc=%s", conn, NULLSTR(xmlDesc));
389 
390     virResetLastError();
391 
392     virCheckConnectReturn(conn, NULL);
393     virCheckNonNullArgGoto(xmlDesc, error);
394     virCheckReadOnlyGoto(conn->flags, error);
395 
396     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterDefineXML) {
397         virNWFilterPtr ret;
398         ret = conn->nwfilterDriver->nwfilterDefineXML(conn, xmlDesc);
399         if (!ret)
400             goto error;
401         return ret;
402     }
403 
404     virReportUnsupportedError();
405 
406  error:
407     virDispatchError(conn);
408     return NULL;
409 }
410 
411 
412 /**
413  * virNWFilterDefineXMLFlags:
414  * @conn: pointer to the hypervisor connection
415  * @xmlDesc: an XML description of the nwfilter
416  * @flags: bitwise-OR of virNWFilterDefineFlags
417  *
418  * Define a new network filter, based on an XML description
419  * similar to the one returned by virNWFilterGetXMLDesc()
420  *
421  * virNWFilterFree should be used to free the resources after the
422  * nwfilter object is no longer needed.
423  *
424  * Returns a new nwfilter object or NULL in case of failure
425  */
426 virNWFilterPtr
virNWFilterDefineXMLFlags(virConnectPtr conn,const char * xmlDesc,unsigned int flags)427 virNWFilterDefineXMLFlags(virConnectPtr conn, const char *xmlDesc, unsigned int flags)
428 {
429     VIR_DEBUG("conn=%p, xmlDesc=%s flags=0x%x", conn, NULLSTR(xmlDesc), flags);
430 
431     virResetLastError();
432 
433     virCheckConnectReturn(conn, NULL);
434     virCheckNonNullArgGoto(xmlDesc, error);
435     virCheckReadOnlyGoto(conn->flags, error);
436 
437     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterDefineXMLFlags) {
438         virNWFilterPtr ret;
439         ret = conn->nwfilterDriver->nwfilterDefineXMLFlags(conn, xmlDesc, flags);
440         if (!ret)
441             goto error;
442         return ret;
443     }
444 
445     virReportUnsupportedError();
446 
447  error:
448     virDispatchError(conn);
449     return NULL;
450 }
451 
452 
453 /**
454  * virNWFilterUndefine:
455  * @nwfilter: a nwfilter object
456  *
457  * Undefine the nwfilter object. This call will not succeed if
458  * a running VM is referencing the filter. This does not free the
459  * associated virNWFilterPtr object.
460  *
461  * Returns 0 in case of success and -1 in case of failure.
462  */
463 int
virNWFilterUndefine(virNWFilterPtr nwfilter)464 virNWFilterUndefine(virNWFilterPtr nwfilter)
465 {
466     virConnectPtr conn;
467     VIR_DEBUG("nwfilter=%p", nwfilter);
468 
469     virResetLastError();
470 
471     virCheckNWFilterReturn(nwfilter, -1);
472     conn = nwfilter->conn;
473 
474     virCheckReadOnlyGoto(conn->flags, error);
475 
476     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterUndefine) {
477         int ret;
478         ret = conn->nwfilterDriver->nwfilterUndefine(nwfilter);
479         if (ret < 0)
480             goto error;
481         return ret;
482     }
483 
484     virReportUnsupportedError();
485 
486  error:
487     virDispatchError(nwfilter->conn);
488     return -1;
489 }
490 
491 
492 /**
493  * virNWFilterGetXMLDesc:
494  * @nwfilter: a nwfilter object
495  * @flags: extra flags; not used yet, so callers should always pass 0
496  *
497  * Provide an XML description of the network filter. The description may be
498  * reused later to redefine the network filter with virNWFilterCreateXML().
499  *
500  * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case
501  * of error. The caller must free() the returned value.
502  */
503 char *
virNWFilterGetXMLDesc(virNWFilterPtr nwfilter,unsigned int flags)504 virNWFilterGetXMLDesc(virNWFilterPtr nwfilter, unsigned int flags)
505 {
506     virConnectPtr conn;
507     VIR_DEBUG("nwfilter=%p, flags=0x%x", nwfilter, flags);
508 
509     virResetLastError();
510 
511     virCheckNWFilterReturn(nwfilter, NULL);
512     conn = nwfilter->conn;
513 
514     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterGetXMLDesc) {
515         char *ret;
516         ret = conn->nwfilterDriver->nwfilterGetXMLDesc(nwfilter, flags);
517         if (!ret)
518             goto error;
519         return ret;
520     }
521 
522     virReportUnsupportedError();
523 
524  error:
525     virDispatchError(nwfilter->conn);
526     return NULL;
527 }
528 
529 
530 /**
531  * virNWFilterRef:
532  * @nwfilter: the nwfilter to hold a reference on
533  *
534  * Increment the reference count on the nwfilter. For each
535  * additional call to this method, there shall be a corresponding
536  * call to virNWFilterFree to release the reference count, once
537  * the caller no longer needs the reference to this object.
538  *
539  * This method is typically useful for applications where multiple
540  * threads are using a connection, and it is required that the
541  * connection remain open until all threads have finished using
542  * it. ie, each new thread using an nwfilter would increment
543  * the reference count.
544  *
545  * Returns 0 in case of success, -1 in case of failure.
546  */
547 int
virNWFilterRef(virNWFilterPtr nwfilter)548 virNWFilterRef(virNWFilterPtr nwfilter)
549 {
550     VIR_DEBUG("nwfilter=%p", nwfilter);
551 
552     virResetLastError();
553 
554     virCheckNWFilterReturn(nwfilter, -1);
555 
556     virObjectRef(nwfilter);
557     return 0;
558 }
559 
560 
561 /**
562  * virConnectListAllNWFilterBindings:
563  * @conn: Pointer to the hypervisor connection.
564  * @bindings: Pointer to a variable to store the array containing the network
565  *            filter objects or NULL if the list is not required (just returns
566  *            number of network filters).
567  * @flags: extra flags; not used yet, so callers should always pass 0
568  *
569  * Collect the list of network filters, and allocate an array to store those
570  * objects.
571  *
572  * Returns the number of network filters found or -1 and sets @filters to  NULL
573  * in case of error.  On success, the array stored into @filters is guaranteed to
574  * have an extra allocated element set to NULL but not included in the return count,
575  * to make iteration easier.  The caller is responsible for calling
576  * virNWFilterFree() on each array element, then calling free() on @filters.
577  */
578 int
virConnectListAllNWFilterBindings(virConnectPtr conn,virNWFilterBindingPtr ** bindings,unsigned int flags)579 virConnectListAllNWFilterBindings(virConnectPtr conn,
580                                   virNWFilterBindingPtr **bindings,
581                                   unsigned int flags)
582 {
583     VIR_DEBUG("conn=%p, bindings=%p, flags=0x%x", conn, bindings, flags);
584 
585     virResetLastError();
586 
587     if (bindings)
588         *bindings = NULL;
589 
590     virCheckConnectReturn(conn, -1);
591 
592     if (conn->nwfilterDriver &&
593         conn->nwfilterDriver->connectListAllNWFilterBindings) {
594         int ret;
595         ret = conn->nwfilterDriver->connectListAllNWFilterBindings(conn, bindings, flags);
596         if (ret < 0)
597             goto error;
598         return ret;
599     }
600 
601     virReportUnsupportedError();
602 
603  error:
604     virDispatchError(conn);
605     return -1;
606 }
607 
608 
609 /**
610  * virNWFilterBindingLookupByPortDev:
611  * @conn: pointer to the hypervisor connection
612  * @portdev: name for the network port device
613  *
614  * Try to lookup a network filter binding on the given hypervisor based
615  * on network port device name.
616  *
617  * virNWFilterBindingFree should be used to free the resources after the
618  * binding object is no longer needed.
619  *
620  * Returns a new binding object or NULL in case of failure.  If the
621  * network filter cannot be found, then VIR_ERR_NO_NWFILTER_BINDING
622  * error is raised.
623  */
624 virNWFilterBindingPtr
virNWFilterBindingLookupByPortDev(virConnectPtr conn,const char * portdev)625 virNWFilterBindingLookupByPortDev(virConnectPtr conn, const char *portdev)
626 {
627     VIR_DEBUG("conn=%p, name=%s", conn, NULLSTR(portdev));
628 
629     virResetLastError();
630 
631     virCheckConnectReturn(conn, NULL);
632     virCheckNonNullArgGoto(portdev, error);
633 
634     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingLookupByPortDev) {
635         virNWFilterBindingPtr ret;
636         ret = conn->nwfilterDriver->nwfilterBindingLookupByPortDev(conn, portdev);
637         if (!ret)
638             goto error;
639         return ret;
640     }
641 
642     virReportUnsupportedError();
643 
644  error:
645     virDispatchError(conn);
646     return NULL;
647 }
648 
649 
650 /**
651  * virNWFilterBindingFree:
652  * @binding: a binding object
653  *
654  * Free the binding object. The running instance is kept alive.
655  * The data structure is freed and should not be used thereafter.
656  *
657  * Returns 0 in case of success and -1 in case of failure.
658  */
659 int
virNWFilterBindingFree(virNWFilterBindingPtr binding)660 virNWFilterBindingFree(virNWFilterBindingPtr binding)
661 {
662     VIR_DEBUG("binding=%p", binding);
663 
664     virResetLastError();
665 
666     virCheckNWFilterBindingReturn(binding, -1);
667 
668     virObjectUnref(binding);
669     return 0;
670 }
671 
672 
673 /**
674  * virNWFilterBindingGetPortDev:
675  * @binding: a binding object
676  *
677  * Get the port dev name for the network filter binding
678  *
679  * Returns a pointer to the name or NULL, the string need not be deallocated
680  * its lifetime will be the same as the binding object.
681  */
682 const char *
virNWFilterBindingGetPortDev(virNWFilterBindingPtr binding)683 virNWFilterBindingGetPortDev(virNWFilterBindingPtr binding)
684 {
685     VIR_DEBUG("binding=%p", binding);
686 
687     virResetLastError();
688 
689     virCheckNWFilterBindingReturn(binding, NULL);
690 
691     return binding->portdev;
692 }
693 
694 
695 /**
696  * virNWFilterBindingGetFilterName:
697  * @binding: a binding object
698  *
699  * Get the filter name for the network filter binding
700  *
701  * Returns a pointer to the name or NULL, the string need not be deallocated
702  * its lifetime will be the same as the binding object.
703  */
704 const char *
virNWFilterBindingGetFilterName(virNWFilterBindingPtr binding)705 virNWFilterBindingGetFilterName(virNWFilterBindingPtr binding)
706 {
707     VIR_DEBUG("binding=%p", binding);
708 
709     virResetLastError();
710 
711     virCheckNWFilterBindingReturn(binding, NULL);
712 
713     return binding->filtername;
714 }
715 
716 
717 /**
718  * virNWFilterBindingCreateXML:
719  * @conn: pointer to the hypervisor connection
720  * @xml: an XML description of the binding
721  * @flags: bitwise-OR of virNWFilterBindingCreateFlags
722  *
723  * Define a new network filter, based on an XML description
724  * similar to the one returned by virNWFilterGetXMLDesc(). This
725  * API may be used to associate a filter with a currently running
726  * guest that does not have a filter defined for a specific network
727  * port. Since the bindings are generally automatically managed by
728  * the hypervisor, using this command to define a filter for a network
729  * port and then starting the guest afterwards may prevent the guest
730  * from starting if it attempts to use the network port and finds a
731  * filter already defined.
732  *
733  * virNWFilterFree should be used to free the resources after the
734  * binding object is no longer needed.
735  *
736  * Returns a new binding object or NULL in case of failure
737  */
738 virNWFilterBindingPtr
virNWFilterBindingCreateXML(virConnectPtr conn,const char * xml,unsigned int flags)739 virNWFilterBindingCreateXML(virConnectPtr conn, const char *xml, unsigned int flags)
740 {
741     VIR_DEBUG("conn=%p, xml=%s", conn, NULLSTR(xml));
742 
743     virResetLastError();
744 
745     virCheckConnectReturn(conn, NULL);
746     virCheckNonNullArgGoto(xml, error);
747     virCheckReadOnlyGoto(conn->flags, error);
748 
749     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingCreateXML) {
750         virNWFilterBindingPtr ret;
751         ret = conn->nwfilterDriver->nwfilterBindingCreateXML(conn, xml, flags);
752         if (!ret)
753             goto error;
754         return ret;
755     }
756 
757     virReportUnsupportedError();
758 
759  error:
760     virDispatchError(conn);
761     return NULL;
762 }
763 
764 
765 /**
766  * virNWFilterBindingDelete:
767  * @binding: a binding object
768  *
769  * Delete the binding object. This does not free the
770  * associated virNWFilterBindingPtr object. This API
771  * may be used to remove the network port binding filter
772  * currently in use for the guest while the guest is
773  * running without needing to restart the guest. Restoring
774  * the network port binding filter for the running guest
775  * would be accomplished by using virNWFilterBindingCreateXML.
776  *
777  * Returns 0 in case of success and -1 in case of failure.
778  */
779 int
virNWFilterBindingDelete(virNWFilterBindingPtr binding)780 virNWFilterBindingDelete(virNWFilterBindingPtr binding)
781 {
782     virConnectPtr conn;
783     VIR_DEBUG("binding=%p", binding);
784 
785     virResetLastError();
786 
787     virCheckNWFilterBindingReturn(binding, -1);
788     conn = binding->conn;
789 
790     virCheckReadOnlyGoto(conn->flags, error);
791 
792     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingDelete) {
793         int ret;
794         ret = conn->nwfilterDriver->nwfilterBindingDelete(binding);
795         if (ret < 0)
796             goto error;
797         return ret;
798     }
799 
800     virReportUnsupportedError();
801 
802  error:
803     virDispatchError(binding->conn);
804     return -1;
805 }
806 
807 
808 /**
809  * virNWFilterBindingGetXMLDesc:
810  * @binding: a binding object
811  * @flags: extra flags; not used yet, so callers should always pass 0
812  *
813  * Provide an XML description of the network filter. The description may be
814  * reused later to redefine the network filter with virNWFilterCreateXML().
815  *
816  * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case
817  * of error. The caller must free() the returned value.
818  */
819 char *
virNWFilterBindingGetXMLDesc(virNWFilterBindingPtr binding,unsigned int flags)820 virNWFilterBindingGetXMLDesc(virNWFilterBindingPtr binding, unsigned int flags)
821 {
822     virConnectPtr conn;
823     VIR_DEBUG("binding=%p, flags=0x%x", binding, flags);
824 
825     virResetLastError();
826 
827     virCheckNWFilterBindingReturn(binding, NULL);
828     conn = binding->conn;
829 
830     if (conn->nwfilterDriver && conn->nwfilterDriver->nwfilterBindingGetXMLDesc) {
831         char *ret;
832         ret = conn->nwfilterDriver->nwfilterBindingGetXMLDesc(binding, flags);
833         if (!ret)
834             goto error;
835         return ret;
836     }
837 
838     virReportUnsupportedError();
839 
840  error:
841     virDispatchError(binding->conn);
842     return NULL;
843 }
844 
845 
846 /**
847  * virNWFilterBindingRef:
848  * @binding: the binding to hold a reference on
849  *
850  * Increment the reference count on the binding. For each
851  * additional call to this method, there shall be a corresponding
852  * call to virNWFilterFree to release the reference count, once
853  * the caller no longer needs the reference to this object.
854  *
855  * This method is typically useful for applications where multiple
856  * threads are using a connection, and it is required that the
857  * connection remain open until all threads have finished using
858  * it. ie, each new thread using an binding would increment
859  * the reference count.
860  *
861  * Returns 0 in case of success, -1 in case of failure.
862  */
863 int
virNWFilterBindingRef(virNWFilterBindingPtr binding)864 virNWFilterBindingRef(virNWFilterBindingPtr binding)
865 {
866     VIR_DEBUG("binding=%p", binding);
867 
868     virResetLastError();
869 
870     virCheckNWFilterBindingReturn(binding, -1);
871 
872     virObjectRef(binding);
873     return 0;
874 }
875