Remove WPA2 and WPA3 service together
[platform/upstream/connman.git] / src / bridge.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
6  *  Copyright (C) 2012-2014  BMW Car IT GmbH.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License version 2 as
10  *  published by the Free Software Foundation.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <sys/ioctl.h>
33 #include <net/if.h>
34 #include <linux/sockios.h>
35 #include <string.h>
36 #include <fcntl.h>
37 #include <linux/if_tun.h>
38
39 #include "connman.h"
40
41 static int set_forward_delay(const char *name, unsigned int delay)
42 {
43         FILE *f;
44         char *forward_delay_path;
45
46         forward_delay_path =
47                 g_strdup_printf("/sys/class/net/%s/bridge/forward_delay", name);
48
49         if (!forward_delay_path)
50                 return -ENOMEM;
51
52         f = fopen(forward_delay_path, "r+");
53
54         g_free(forward_delay_path);
55
56         if (!f)
57                 return -errno;
58
59         fprintf(f, "%u", delay);
60
61         fclose(f);
62
63         return 0;
64 }
65
66 int __connman_bridge_create(const char *name)
67 {
68         int sk, err;
69
70         DBG("name %s", name);
71
72         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
73         if (sk < 0)
74                 return -EOPNOTSUPP;
75
76         if (ioctl(sk, SIOCBRADDBR, name) == -1) {
77                 err = -errno;
78                 if (err != -EEXIST) {
79                         close(sk);
80                         return -EOPNOTSUPP;
81                 }
82         }
83
84         err = set_forward_delay(name, 0);
85
86         if (err < 0)
87                 ioctl(sk, SIOCBRDELBR, name);
88
89         close(sk);
90
91         return err;
92 }
93
94 int __connman_bridge_remove(const char *name)
95 {
96         int sk, err;
97
98         DBG("name %s", name);
99
100         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
101         if (sk < 0)
102                 return -EOPNOTSUPP;
103
104         err = ioctl(sk, SIOCBRDELBR, name);
105
106         close(sk);
107
108         if (err < 0)
109                 return -EOPNOTSUPP;
110
111         return 0;
112 }
113
114 int __connman_bridge_enable(const char *name, const char *ip_address,
115                         int prefix_len, const char *broadcast)
116 {
117         int err, index;
118
119         index = connman_inet_ifindex(name);
120         if (index < 0)
121                 return index;
122
123         err = __connman_inet_modify_address(RTM_NEWADDR,
124                                 NLM_F_REPLACE | NLM_F_ACK, index, AF_INET,
125                                 ip_address, NULL, prefix_len, broadcast,
126                                 false);
127         if (err < 0)
128                 return err;
129
130         return connman_inet_ifup(index);
131 }
132
133 int __connman_bridge_disable(const char *name)
134 {
135         int index;
136
137         index = connman_inet_ifindex(name);
138         if (index < 0)
139                 return index;
140
141         return connman_inet_ifdown(index);
142 }