1 /* 2 * netifd - network interface daemon 3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 7 * as published by the Free Software Foundation 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 */ 14 #define _GNU_SOURCE 15 16 #include <string.h> 17 #include <stdlib.h> 18 #include <stdio.h> 19 20 #include "netifd.h" 21 #include "proto.h" 22 #include "handler.h" 23 #include "proto-ext.h" 24 25 static int proto_fd = -1; 26 27 struct proto_shell_handler { 28 struct list_head list; 29 struct proto_handler proto; 30 char *config_buf; 31 char *script_name; 32 bool init_available; 33 34 struct uci_blob_param_list config; 35 }; 36 37 static int 38 proto_shell_start(struct proto_ext_state *state, const char *action, 39 const char *config, char **envp) 40 { 41 struct proto_shell_handler *handler; 42 const char *argv[7]; 43 int i = 0; 44 45 handler = container_of(state->proto.handler, struct proto_shell_handler, proto); 46 47 argv[i++] = handler->script_name; 48 argv[i++] = handler->proto.name; 49 argv[i++] = action; 50 argv[i++] = state->proto.iface->name; 51 argv[i++] = config; 52 if (state->proto.iface->main_dev.dev) 53 argv[i++] = state->proto.iface->main_dev.dev->ifname; 54 argv[i] = NULL; 55 56 return netifd_start_process(argv, envp, &state->script_task); 57 } 58 59 static int 60 proto_shell_handler(struct interface_proto_state *proto, 61 enum interface_proto_cmd cmd, bool force) 62 { 63 struct proto_ext_state *state; 64 65 state = container_of(proto, struct proto_ext_state, proto); 66 return proto_ext_run(state, cmd, force, proto_shell_start); 67 } 68 69 static struct interface_proto_state * 70 proto_shell_attach(const struct proto_handler *h, struct interface *iface, 71 struct blob_attr *attr) 72 { 73 struct proto_ext_state *state; 74 75 state = calloc(1, sizeof(*state)); 76 if (!state) 77 return NULL; 78 79 proto_ext_state_init(state, iface, attr, proto_fd); 80 if (!state->config) { 81 free(state); 82 return NULL; 83 } 84 85 state->proto.cb = proto_shell_handler; 86 87 return &state->proto; 88 } 89 90 static void 91 proto_shell_add_handler(const char *script, const char *name, json_object *obj) 92 { 93 struct proto_shell_handler *handler; 94 struct proto_handler *proto; 95 json_object *config, *tmp; 96 char *proto_name, *script_name; 97 98 handler = calloc_a(sizeof(*handler), 99 &proto_name, strlen(name) + 1, 100 &script_name, strlen(script) + 1); 101 if (!handler) 102 return; 103 104 handler->script_name = strcpy(script_name, script); 105 106 proto = &handler->proto; 107 proto->name = strcpy(proto_name, name); 108 proto->config_params = &handler->config; 109 proto->attach = proto_shell_attach; 110 111 tmp = json_get_field(obj, "no-device", json_type_boolean); 112 if (tmp && json_object_get_boolean(tmp)) 113 handler->proto.flags |= PROTO_FLAG_NODEV; 114 115 tmp = json_get_field(obj, "no-device-config", json_type_boolean); 116 if (tmp && json_object_get_boolean(tmp)) 117 handler->proto.flags |= PROTO_FLAG_NODEV_CONFIG; 118 119 tmp = json_get_field(obj, "no-proto-task", json_type_boolean); 120 if (tmp && json_object_get_boolean(tmp)) 121 handler->proto.flags |= PROTO_FLAG_NO_TASK; 122 123 tmp = json_get_field(obj, "available", json_type_boolean); 124 if (tmp && json_object_get_boolean(tmp)) 125 handler->proto.flags |= PROTO_FLAG_INIT_AVAILABLE; 126 127 tmp = json_get_field(obj, "renew-handler", json_type_boolean); 128 if (tmp && json_object_get_boolean(tmp)) 129 handler->proto.flags |= PROTO_FLAG_RENEW_AVAILABLE; 130 131 tmp = json_get_field(obj, "lasterror", json_type_boolean); 132 if (tmp && json_object_get_boolean(tmp)) 133 handler->proto.flags |= PROTO_FLAG_LASTERROR; 134 135 tmp = json_get_field(obj, "teardown-on-l3-link-down", json_type_boolean); 136 if (tmp && json_object_get_boolean(tmp)) 137 handler->proto.flags |= PROTO_FLAG_TEARDOWN_ON_L3_LINK_DOWN; 138 139 config = json_get_field(obj, "config", json_type_array); 140 if (config) 141 handler->config_buf = netifd_handler_parse_config(&handler->config, config); 142 143 D(INTERFACE, "Add handler for script %s: %s", script, proto->name); 144 add_proto_handler(proto); 145 } 146 147 void proto_shell_init(void) 148 { 149 proto_fd = netifd_open_subdir("proto"); 150 if (proto_fd < 0) 151 return; 152 153 netifd_init_script_handlers(proto_fd, proto_shell_add_handler); 154 } 155
This page was automatically generated by LXR 0.3.1. • OpenWrt