[PATCH 2/2] util:veth: Create veth device pair by netlink
Shi Lei
shi_lei at massclouds.com
Mon Nov 23 02:06:07 UTC 2020
>On 11/17/20 1:48 AM, Shi Lei wrote:
>> When netlink is supported, use netlink to create veth device pair
>> rather than 'ip link' command.
>>
>> Signed-off-by: Shi Lei <shi_lei at massclouds.com>
>> ---
>> src/util/virnetdevveth.c | 39 ++++++++++++++++++++++++++++++---------
>> 1 file changed, 30 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/util/virnetdevveth.c b/src/util/virnetdevveth.c
>> index b3eee1af..996bf5dd 100644
>> --- a/src/util/virnetdevveth.c
>> +++ b/src/util/virnetdevveth.c
>> @@ -27,6 +27,7 @@
>> #include "virfile.h"
>> #include "virstring.h"
>> #include "virnetdev.h"
>> +#include "virnetlink.h"
>>
>> #define VIR_FROM_THIS VIR_FROM_NONE
>>
>> @@ -116,7 +117,6 @@ int virNetDevVethCreate(char** veth1, char** veth2)
>> for (i = 0; i < MAX_VETH_RETRIES; i++) {
>> g_autofree char *veth1auto = NULL;
>> g_autofree char *veth2auto = NULL;
>> - g_autoptr(virCommand) cmd = NULL;
>>
>> int status;
>> if (!*veth1) {
>> @@ -136,15 +136,32 @@ int virNetDevVethCreate(char** veth1, char** veth2)
>> vethNum = veth2num + 1;
>> }
>>
>> - cmd = virCommandNew("ip");
>> - virCommandAddArgList(cmd, "link", "add",
>> - *veth1 ? *veth1 : veth1auto,
>> - "type", "veth", "peer", "name",
>> - *veth2 ? *veth2 : veth2auto,
>> - NULL);
>> +#if defined(WITH_LIBNL)
>> + {
>> + int error = 0;
>> + virNetlinkNewLinkData data = {
>> + .veth_peer = *veth2 ? *veth2 : veth2auto,
>> + };
>>
>> - if (virCommandRun(cmd, &status) < 0)
>> - goto cleanup;
>> + status = virNetlinkNewLink(*veth1 ? *veth1 : veth1auto,
>> + "veth", &data, &error);
>> + if (status < 0)
>> + goto cleanup;
>> + }
>> +#else
>> + {
>> + g_autoptr(virCommand) cmd = NULL;
>> + cmd = virCommandNew("ip");
>> + virCommandAddArgList(cmd, "link", "add",
>> + *veth1 ? *veth1 : veth1auto,
>> + "type", "veth", "peer", "name",
>> + *veth2 ? *veth2 : veth2auto,
>> + NULL);
>> +
>> + if (virCommandRun(cmd, &status) < 0)
>> + goto cleanup;
>> + }
>> +#endif /* WITH_LIBNL */
>
>
>Although it isn't a hard/fast rule, we generally prefer to have complete
>functions within an #ifdefs rather then putting #ifdefs in the middle of
>a function. Could you put these bits into smaller functions, patterned
>like below, and then call the vir*Internal() functions from the existing
>functions?
>
>(other than that this looks fine, although I haven't actually tried
>*running* it yet :-))
Okay. It looks fine.
>
>
>#if defined(WITH_LIBNL)
>
>int
>
>virNetDevVethCreateInternal(char *veth1, char *veth2)
>
>{
>
> int error;
>
> virNetlinkNewLinkData data = { .veth_peer = veth2 };
>
>
> return virNetlinkNewLink(veth1, "veth", &data, &error);
>
>}
>
>
>
>int
>
>virNetDevVethDeleteInternal(char *veth)
>
>{
>
> return virNetlinkDelLink(veth, NULL);
>
>}
>
>
>
>#else
>
>
>
>int
>
>virNetDevVethCreateInternal(char *veth1, char *veth2)
>
>{
>
> g_autoptr(virCommand) cmd = virCommandNew("ip");
>
>
> virCommandAddArgList(cmd, "link", "add", veth1, veth2);
>
> return virCommandRun(cmd, NULL);
>
>}
>
>
>
>int
>
>virNetDevVethDeleteInternal(char *veth)
>
>{
>
> int status;
> g_autoptr(virCommand) cmd = virCommandNewArgList("ip", "link",
>"del", veth, NULL);
>
> if (virCommandRun(cmd, &status) < 0)
> return -1;
>
> if (status != 0) {
> if (!virNetDevExists(veth)) {
> VIR_DEBUG("Device %s already deleted (by kernel namespace
>cleanup)", veth);
> return 0;
> }
> virReportError(VIR_ERR_INTERNAL_ERROR,
> _("Failed to delete veth device %s"), veth);
> return -1;
> }
>
> return 0;
>}
>
>
>>
>> if (status == 0) {
>> if (veth1auto) {
>> @@ -188,6 +205,9 @@ int virNetDevVethCreate(char** veth1, char** veth2)
>> */
>> int virNetDevVethDelete(const char *veth)
>> {
>> +#if defined(WITH_LIBNL)
>> + return virNetlinkDelLink(veth, NULL);
>> +#else
>> int status;
>> g_autoptr(virCommand) cmd = virCommandNewArgList("ip", "link",
>> "del", veth, NULL);
>> @@ -206,4 +226,5 @@ int virNetDevVethDelete(const char *veth)
>> }
>>
>> return 0;
>> +#endif /* WITH_LIBNL */
>> }
>
>
>(Aside from this, it looks like veth interface naming could benefit from
>the same simplifications that I did to tap and macvtap awhile back
>(basically changing the auto-generated names to never re-use a name -
>commit 95089f481 and commit d7f38beb2e). But that isn't something for
>this series, just another thing to add to the to-do list :-))
>
Oh. Perhaps I can try it in another series.
Thanks!
Shi Lei
More information about the libvir-list
mailing list