~ubuntu-branches/ubuntu/trusty/systemd/trusty

« back to all changes in this revision

Viewing changes to src/core/loopback-setup.c

Tags: upstream-202
ImportĀ upstreamĀ versionĀ 202

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
        union {
89
89
                struct sockaddr sa;
90
90
                struct sockaddr_nl nl;
91
 
        } sa;
 
91
        } sa = {
 
92
                .nl.nl_family = AF_NETLINK,
 
93
        };
 
94
 
92
95
        union {
93
96
                struct nlmsghdr header;
94
97
                uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
95
98
                            NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
96
99
                            RTA_LENGTH(sizeof(struct in6_addr))];
97
 
        } request;
 
100
        } request = {
 
101
                .header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
 
102
                .header.nlmsg_type = RTM_NEWADDR,
 
103
                .header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK,
 
104
                .header.nlmsg_seq = *requests + 1,
 
105
        };
98
106
 
99
107
        struct ifaddrmsg *ifaddrmsg;
100
108
        uint32_t ipv4_address = htonl(INADDR_LOOPBACK);
101
109
        int r;
102
110
 
103
 
        zero(request);
104
 
 
105
 
        request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
106
 
        request.header.nlmsg_type = RTM_NEWADDR;
107
 
        request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK;
108
 
        request.header.nlmsg_seq = *requests + 1;
109
 
 
110
111
        ifaddrmsg = NLMSG_DATA(&request.header);
111
112
        ifaddrmsg->ifa_family = AF_INET;
112
113
        ifaddrmsg->ifa_prefixlen = 8;
114
115
        ifaddrmsg->ifa_scope = RT_SCOPE_HOST;
115
116
        ifaddrmsg->ifa_index = if_loopback;
116
117
 
117
 
        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &ipv4_address, sizeof(ipv4_address));
 
118
        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL,
 
119
                       &ipv4_address, sizeof(ipv4_address));
118
120
        if (r < 0)
119
121
                return r;
120
122
 
121
 
        zero(sa);
122
 
        sa.nl.nl_family = AF_NETLINK;
123
 
 
124
123
        if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
125
124
                return -errno;
126
125
        (*requests)++;
134
133
        ifaddrmsg->ifa_family = AF_INET6;
135
134
        ifaddrmsg->ifa_prefixlen = 128;
136
135
 
137
 
        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL, &in6addr_loopback, sizeof(in6addr_loopback));
 
136
        r = add_rtattr(&request.header, sizeof(request), IFA_LOCAL,
 
137
                       &in6addr_loopback, sizeof(in6addr_loopback));
138
138
        if (r < 0)
139
139
                return r;
140
140
 
149
149
        union {
150
150
                struct sockaddr sa;
151
151
                struct sockaddr_nl nl;
152
 
        } sa;
 
152
        } sa = {
 
153
                .nl.nl_family = AF_NETLINK,
 
154
        };
 
155
 
153
156
        union {
154
157
                struct nlmsghdr header;
155
158
                uint8_t buf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
156
159
                            NLMSG_ALIGN(sizeof(struct ifinfomsg))];
157
 
        } request;
 
160
        } request = {
 
161
                .header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
 
162
                .header.nlmsg_type = RTM_NEWLINK,
 
163
                .header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK,
 
164
                .header.nlmsg_seq = *requests + 1,
 
165
        };
158
166
 
159
167
        struct ifinfomsg *ifinfomsg;
160
168
 
161
 
        zero(request);
162
 
 
163
 
        request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
164
 
        request.header.nlmsg_type = RTM_NEWLINK;
165
 
        request.header.nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
166
 
        request.header.nlmsg_seq = *requests + 1;
167
 
 
168
169
        ifinfomsg = NLMSG_DATA(&request.header);
169
170
        ifinfomsg->ifi_family = AF_UNSPEC;
170
171
        ifinfomsg->ifi_index = if_loopback;
171
172
        ifinfomsg->ifi_flags = IFF_UP;
172
173
        ifinfomsg->ifi_change = IFF_UP;
173
174
 
174
 
        zero(sa);
175
 
        sa.nl.nl_family = AF_NETLINK;
176
 
 
177
175
        if (sendto_loop(fd, &request, request.header.nlmsg_len, 0, &sa.sa, sizeof(sa)) < 0)
178
176
                return -errno;
179
177
 
229
227
}
230
228
 
231
229
static int check_loopback(void) {
232
 
        int r, fd;
 
230
        int r;
 
231
        _cleanup_close_ int fd;
233
232
        union {
234
233
                struct sockaddr sa;
235
234
                struct sockaddr_in in;
236
 
        } sa;
 
235
        } sa = {
 
236
                .in.sin_family = AF_INET,
 
237
                .in.sin_addr.s_addr = INADDR_LOOPBACK,
 
238
        };
237
239
 
238
240
        /* If we failed to set up the loop back device, check whether
239
241
         * it might already be set up */
242
244
        if (fd < 0)
243
245
                return -errno;
244
246
 
245
 
        zero(sa);
246
 
        sa.in.sin_family = AF_INET;
247
 
        sa.in.sin_addr.s_addr = INADDR_LOOPBACK;
248
 
 
249
247
        if (bind(fd, &sa.sa, sizeof(sa.in)) >= 0)
250
248
                r = 1;
251
249
        else
252
250
                r = errno == EADDRNOTAVAIL ? 0 : -errno;
253
251
 
254
 
        close_nointr_nofail(fd);
255
 
 
256
252
        return r;
257
253
}
258
254
 
261
257
        union {
262
258
                struct sockaddr sa;
263
259
                struct sockaddr_nl nl;
264
 
        } sa;
 
260
        } sa = {
 
261
                .nl.nl_family = AF_NETLINK,
 
262
        };
265
263
        unsigned requests = 0, i;
266
 
        int fd;
 
264
        _cleanup_close_ int fd = -1;
267
265
        bool eperm = false;
268
266
 
269
267
        errno = 0;
275
273
        if (fd < 0)
276
274
                return -errno;
277
275
 
278
 
        zero(sa);
279
 
        sa.nl.nl_family = AF_NETLINK;
280
276
        if (bind(fd, &sa.sa, sizeof(sa)) < 0) {
281
277
                r = -errno;
282
 
                goto finish;
 
278
                goto error;
283
279
        }
284
280
 
285
281
        r = add_adresses(fd, if_loopback, &requests);
286
282
        if (r < 0)
287
 
                goto finish;
 
283
                goto error;
288
284
 
289
285
        r = start_interface(fd, if_loopback, &requests);
290
286
        if (r < 0)
291
 
                goto finish;
 
287
                goto error;
292
288
 
293
289
        for (i = 0; i < requests; i++) {
294
290
                r = read_response(fd, requests);
296
292
                if (r == -EPERM)
297
293
                        eperm = true;
298
294
                else if (r  < 0)
299
 
                        goto finish;
 
295
                        goto error;
300
296
        }
301
297
 
302
298
        if (eperm && check_loopback() < 0) {
303
299
                r = -EPERM;
304
 
                goto finish;
 
300
                goto error;
305
301
        }
306
302
 
307
 
        r = 0;
308
 
 
309
 
finish:
310
 
        if (r < 0)
311
 
                log_warning("Failed to configure loopback device: %s", strerror(-r));
312
 
 
313
 
        if (fd >= 0)
314
 
                close_nointr_nofail(fd);
315
 
 
 
303
        return 0;
 
304
 
 
305
error:
 
306
        log_warning("Failed to configure loopback device: %s", strerror(-r));
316
307
        return r;
317
308
}