• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/netifd/proto-shell.c

  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