fix interface event handling, suppress redundant down events
[project/netifd.git] / device.h
1 #ifndef __LL_H
2 #define __LL_H
3
4 #include <libubox/avl.h>
5 #include <netinet/in.h>
6
7 struct device;
8 struct device_user;
9 struct device_hotplug_ops;
10
11 typedef int (*device_state_cb)(struct device *, bool up);
12
13 enum {
14         DEV_ATTR_TYPE,
15         DEV_ATTR_IFNAME,
16         DEV_ATTR_MTU,
17         DEV_ATTR_MACADDR,
18         DEV_ATTR_TXQUEUELEN,
19         __DEV_ATTR_MAX,
20 };
21
22 enum dev_change_type {
23         DEV_CONFIG_NO_CHANGE,
24         DEV_CONFIG_APPLIED,
25         DEV_CONFIG_RECREATE,
26 };
27
28 struct device_type {
29         struct list_head list;
30         const char *name;
31
32         const struct config_param_list *config_params;
33
34         struct device *(*create)(const char *name, struct blob_attr *attr);
35         void (*config_init)(struct device *);
36         enum dev_change_type (*reload)(struct device *, struct blob_attr *);
37         void (*dump_info)(struct device *, struct blob_buf *buf);
38         void (*dump_stats)(struct device *, struct blob_buf *buf);
39         int (*check_state)(struct device *);
40         void (*free)(struct device *);
41 };
42
43 enum {
44         DEV_OPT_MTU             = (1 << 0),
45         DEV_OPT_MACADDR         = (1 << 1),
46         DEV_OPT_TXQUEUELEN      = (1 << 2)
47 };
48
49 /* events broadcasted to all users of a device */
50 enum device_event {
51         DEV_EVENT_ADD,
52         DEV_EVENT_REMOVE,
53
54         DEV_EVENT_SETUP,
55         DEV_EVENT_TEARDOWN,
56         DEV_EVENT_UP,
57         DEV_EVENT_DOWN,
58
59         DEV_EVENT_LINK_UP,
60         DEV_EVENT_LINK_DOWN,
61 };
62
63 /*
64  * device dependency with callbacks
65  */
66 struct device_user {
67         struct list_head list;
68
69         bool claimed;
70         bool hotplug;
71
72         struct device *dev;
73         void (*cb)(struct device_user *, enum device_event);
74 };
75
76 /* 
77  * link layer device. typically represents a linux network device.
78  * can be used to support VLANs as well
79  */
80 struct device {
81         const struct device_type *type;
82
83         struct avl_node avl;
84         struct list_head users;
85
86         char ifname[IFNAMSIZ + 1];
87         int ifindex;
88
89         struct blob_attr *config;
90         bool config_pending;
91         bool present;
92         int active;
93         bool external;
94
95         bool current_config;
96         bool default_config;
97
98         /* set interface up or down */
99         device_state_cb set_state;
100
101         const struct device_hotplug_ops *hotplug_ops;
102
103         struct device_user parent;
104
105         /* settings */
106         unsigned int flags;
107
108         unsigned int mtu;
109         unsigned int txqueuelen;
110         uint8_t macaddr[6];
111 };
112
113 struct device_hotplug_ops {
114         int (*add)(struct device *main, struct device *member);
115         int (*del)(struct device *main, struct device *member);
116 };
117
118 extern const struct config_param_list device_attr_list;
119 extern const struct device_type simple_device_type;
120 extern const struct device_type bridge_device_type;
121
122 void device_lock(void);
123 void device_unlock(void);
124
125 struct device *device_create(const char *name, const struct device_type *type,
126                              struct blob_attr *config);
127 void device_init_settings(struct device *dev, struct blob_attr **tb);
128 void device_init_pending(void);
129
130 enum dev_change_type
131 device_set_config(struct device *dev, const struct device_type *type,
132                   struct blob_attr *attr);
133
134 void device_reset_config(void);
135 void device_reset_old(void);
136
137 void device_init_virtual(struct device *dev, const struct device_type *type, const char *name);
138 int device_init(struct device *iface, const struct device_type *type, const char *ifname);
139 void device_cleanup(struct device *iface);
140 struct device *device_get(const char *name, int create);
141 void device_add_user(struct device_user *dep, struct device *iface);
142 void device_remove_user(struct device_user *dep);
143
144 void device_set_present(struct device *dev, bool state);
145 int device_claim(struct device_user *dep);
146 void device_release(struct device_user *dep);
147 int device_check_state(struct device *dev);
148 void device_dump_status(struct blob_buf *b, struct device *dev);
149
150 static inline void
151 device_free(struct device *dev)
152 {
153         dev->type->free(dev);
154 }
155
156 void device_free_unused(struct device *dev);
157
158 struct device *get_vlan_device_chain(const char *ifname, bool create);
159 void alias_notify_device(const char *name, struct device *dev);
160
161 #endif