rt-link.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <ynl.h>
  5. #include <arpa/inet.h>
  6. #include <net/if.h>
  7. #include "rt-link-user.h"
  8. static void rt_link_print(struct rt_link_getlink_rsp *r)
  9. {
  10. unsigned int i;
  11. printf("%3d: ", r->_hdr.ifi_index);
  12. if (r->_len.ifname)
  13. printf("%16s: ", r->ifname);
  14. if (r->_present.mtu)
  15. printf("mtu %5d ", r->mtu);
  16. if (r->linkinfo._len.kind)
  17. printf("kind %-8s ", r->linkinfo.kind);
  18. else
  19. printf(" %8s ", "");
  20. if (r->prop_list._count.alt_ifname) {
  21. printf("altname ");
  22. for (i = 0; i < r->prop_list._count.alt_ifname; i++)
  23. printf("%s ", r->prop_list.alt_ifname[i]->str);
  24. printf(" ");
  25. }
  26. if (r->linkinfo._present.data && r->linkinfo.data._present.netkit) {
  27. struct rt_link_linkinfo_netkit_attrs *netkit;
  28. const char *name;
  29. netkit = &r->linkinfo.data.netkit;
  30. printf("primary %d ", netkit->primary);
  31. name = NULL;
  32. if (netkit->_present.policy)
  33. name = rt_link_netkit_policy_str(netkit->policy);
  34. if (name)
  35. printf("policy %s ", name);
  36. }
  37. printf("\n");
  38. }
  39. static int rt_link_create_netkit(struct ynl_sock *ys)
  40. {
  41. struct rt_link_getlink_ntf *ntf_gl;
  42. struct rt_link_newlink_req *req;
  43. struct ynl_ntf_base_type *ntf;
  44. int ret;
  45. req = rt_link_newlink_req_alloc();
  46. if (!req) {
  47. fprintf(stderr, "Can't alloc req\n");
  48. return -1;
  49. }
  50. /* rtnetlink doesn't provide info about the created object.
  51. * It expects us to set the ECHO flag and the dig the info out
  52. * of the notifications...
  53. */
  54. rt_link_newlink_req_set_nlflags(req, NLM_F_CREATE | NLM_F_ECHO);
  55. rt_link_newlink_req_set_linkinfo_kind(req, "netkit");
  56. /* Test error messages */
  57. rt_link_newlink_req_set_linkinfo_data_netkit_policy(req, 10);
  58. ret = rt_link_newlink(ys, req);
  59. if (ret) {
  60. printf("Testing error message for policy being bad:\n\t%s\n", ys->err.msg);
  61. } else {
  62. fprintf(stderr, "Warning: unexpected success creating netkit with bad attrs\n");
  63. goto created;
  64. }
  65. rt_link_newlink_req_set_linkinfo_data_netkit_policy(req, NETKIT_DROP);
  66. ret = rt_link_newlink(ys, req);
  67. created:
  68. rt_link_newlink_req_free(req);
  69. if (ret) {
  70. fprintf(stderr, "YNL: %s\n", ys->err.msg);
  71. return -1;
  72. }
  73. if (!ynl_has_ntf(ys)) {
  74. fprintf(stderr,
  75. "Warning: interface created but received no notification, won't delete the interface\n");
  76. return 0;
  77. }
  78. ntf = ynl_ntf_dequeue(ys);
  79. if (ntf->cmd != RTM_NEWLINK) {
  80. fprintf(stderr,
  81. "Warning: unexpected notification type, won't delete the interface\n");
  82. return 0;
  83. }
  84. ntf_gl = (void *)ntf;
  85. ret = ntf_gl->obj._hdr.ifi_index;
  86. ynl_ntf_free(ntf);
  87. return ret;
  88. }
  89. static void rt_link_del(struct ynl_sock *ys, int ifindex)
  90. {
  91. struct rt_link_dellink_req *req;
  92. req = rt_link_dellink_req_alloc();
  93. if (!req) {
  94. fprintf(stderr, "Can't alloc req\n");
  95. return;
  96. }
  97. req->_hdr.ifi_index = ifindex;
  98. if (rt_link_dellink(ys, req))
  99. fprintf(stderr, "YNL: %s\n", ys->err.msg);
  100. else
  101. fprintf(stderr,
  102. "Trying to delete a Netkit interface (ifindex %d)\n",
  103. ifindex);
  104. rt_link_dellink_req_free(req);
  105. }
  106. int main(int argc, char **argv)
  107. {
  108. struct rt_link_getlink_req_dump *req;
  109. struct rt_link_getlink_list *rsp;
  110. struct ynl_error yerr;
  111. struct ynl_sock *ys;
  112. int created = 0;
  113. ys = ynl_sock_create(&ynl_rt_link_family, &yerr);
  114. if (!ys) {
  115. fprintf(stderr, "YNL: %s\n", yerr.msg);
  116. return 1;
  117. }
  118. if (argc > 1) {
  119. fprintf(stderr, "Trying to create a Netkit interface\n");
  120. created = rt_link_create_netkit(ys);
  121. if (created < 0)
  122. goto err_destroy;
  123. }
  124. req = rt_link_getlink_req_dump_alloc();
  125. if (!req)
  126. goto err_del_ifc;
  127. rsp = rt_link_getlink_dump(ys, req);
  128. rt_link_getlink_req_dump_free(req);
  129. if (!rsp)
  130. goto err_close;
  131. if (ynl_dump_empty(rsp))
  132. fprintf(stderr, "Error: no links reported\n");
  133. ynl_dump_foreach(rsp, link)
  134. rt_link_print(link);
  135. rt_link_getlink_list_free(rsp);
  136. if (created)
  137. rt_link_del(ys, created);
  138. ynl_sock_destroy(ys);
  139. return 0;
  140. err_close:
  141. fprintf(stderr, "YNL: %s\n", ys->err.msg);
  142. err_del_ifc:
  143. if (created)
  144. rt_link_del(ys, created);
  145. err_destroy:
  146. ynl_sock_destroy(ys);
  147. return 2;
  148. }