registry.c (2014B)
1 #include <stdio.h> 2 #include <string.h> 3 #include <strings.h> 4 5 #include "dataplane.h" 6 7 #include "registry.h" 8 9 #define DP_MAX_BACKENDS 16 10 11 static const struct dp_ops *backend[DP_MAX_BACKENDS]; 12 static int backend_count = 0; 13 static const struct dp_ops *active = NULL; 14 15 int dp_register(const struct dp_ops *ops) { 16 if (!ops) return DP_RET_ERROR; 17 18 if (ops->abi != LINKD_DATAPLANE_ABI) { 19 fprintf(stderr, "dataplane: refusing backend `%s`: abi %u, expected %u\n", 20 ops->name ? ops->name : "(unnamed)", ops->abi, LINKD_DATAPLANE_ABI); 21 return DP_RET_ERROR; 22 } 23 24 if (!ops->name || !ops->probe || !ops->init) { 25 fprintf(stderr, "dataplane: refusing incomplete backend\n"); 26 return DP_RET_ERROR; 27 } 28 29 if (backend_count >= DP_MAX_BACKENDS) { 30 fprintf(stderr, "dataplane: backend table full, dropping `%s`\n", ops->name); 31 return DP_RET_ERROR; 32 } 33 34 backend[backend_count++] = ops; 35 return DP_RET_OK; 36 } 37 38 int dp_select(const char *force) { 39 int i; 40 41 if (force) { 42 for (i = 0; i < backend_count; i++) { 43 if (!strcasecmp(backend[i]->name, force)) { 44 active = backend[i]; 45 fprintf(stderr, "dataplane: using `%s` (forced)\n", active->name); 46 return DP_RET_OK; 47 } 48 } 49 fprintf(stderr, "dataplane: no backend named `%s`\n", force); 50 return DP_RET_ERROR; 51 } 52 53 // Plugins are probed before the built-in kernel backend, which is 54 // registered first and always succeeds -- so iterate in reverse. 55 for (i = backend_count - 1; i >= 0; i--) { 56 if (backend[i]->probe() != DP_RET_OK) continue; 57 active = backend[i]; 58 fprintf(stderr, "dataplane: using `%s`\n", active->name); 59 return DP_RET_OK; 60 } 61 62 fprintf(stderr, "dataplane: no usable backend\n"); 63 return DP_RET_ERROR; 64 } 65 66 const struct dp_ops * dp_active(void) { 67 return active; 68 } 69 70 int dp_init(void) { 71 if (!active) return DP_RET_ERROR; 72 return active->init(); 73 } 74 75 void dp_fini(void) { 76 if (!active) return; 77 if (active->fini) active->fini(); 78 active = NULL; 79 }