]>
Commit | Line | Data |
---|---|---|
a14bc59f | 1 | /* |
67a4917b | 2 | * Copyright (c) 2009, 2010 Nicira Networks. |
a14bc59f BP |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
064af421 BP |
17 | #include <config.h> |
18 | #include <errno.h> | |
19 | #include <inttypes.h> | |
20 | #include <net/if.h> | |
21 | #include <poll.h> | |
22 | #include <sys/socket.h> | |
23 | #include <sys/uio.h> | |
24 | #include <stddef.h> | |
25 | #include <linux/rtnetlink.h> | |
26 | #include "netlink.h" | |
2fe27d5a | 27 | #include "netlink-socket.h" |
064af421 BP |
28 | #include "ofpbuf.h" |
29 | #include "poll-loop.h" | |
30 | #include "timeval.h" | |
31 | #include "util.h" | |
32 | #include "vlog.h" | |
33 | ||
34 | static const struct nl_policy rtnlgrp_link_policy[] = { | |
35 | [IFLA_IFNAME] = { .type = NL_A_STRING, .optional = false }, | |
36 | [IFLA_MASTER] = { .type = NL_A_U32, .optional = true }, | |
37 | }; | |
38 | ||
39 | int | |
67a4917b | 40 | main(int argc OVS_UNUSED, char *argv[]) |
064af421 BP |
41 | { |
42 | struct nl_sock *sock; | |
43 | int error; | |
44 | ||
45 | set_program_name(argv[0]); | |
480ce8ab | 46 | vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG); |
064af421 BP |
47 | |
48 | error = nl_sock_create(NETLINK_ROUTE, RTNLGRP_LINK, 0, 0, &sock); | |
49 | if (error) { | |
50 | ovs_fatal(error, "could not create rtnetlink socket"); | |
51 | } | |
52 | ||
53 | for (;;) { | |
54 | struct ofpbuf *buf; | |
55 | ||
56 | error = nl_sock_recv(sock, &buf, false); | |
57 | if (error == EAGAIN) { | |
58 | /* Nothing to do. */ | |
59 | } else if (error == ENOBUFS) { | |
60 | ovs_error(0, "network monitor socket overflowed"); | |
61 | } else if (error) { | |
62 | ovs_fatal(error, "error on network monitor socket"); | |
63 | } else { | |
64 | struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)]; | |
65 | struct nlmsghdr *nlh; | |
66 | struct ifinfomsg *iim; | |
67 | ||
68 | nlh = ofpbuf_at(buf, 0, NLMSG_HDRLEN); | |
69 | iim = ofpbuf_at(buf, NLMSG_HDRLEN, sizeof *iim); | |
70 | if (!iim) { | |
71 | ovs_error(0, "received bad rtnl message (no ifinfomsg)"); | |
72 | ofpbuf_delete(buf); | |
73 | continue; | |
74 | } | |
75 | ||
76 | if (!nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg), | |
77 | rtnlgrp_link_policy, | |
78 | attrs, ARRAY_SIZE(rtnlgrp_link_policy))) { | |
79 | ovs_error(0, "received bad rtnl message (policy)"); | |
80 | ofpbuf_delete(buf); | |
81 | continue; | |
82 | } | |
83 | printf("netdev %s changed (%s):\n", | |
84 | nl_attr_get_string(attrs[IFLA_IFNAME]), | |
85 | (nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK" | |
86 | : nlh->nlmsg_type == RTM_DELLINK ? "RTM_DELLINK" | |
87 | : nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK" | |
88 | : nlh->nlmsg_type == RTM_SETLINK ? "RTM_SETLINK" | |
89 | : "other")); | |
90 | if (attrs[IFLA_MASTER]) { | |
91 | uint32_t idx = nl_attr_get_u32(attrs[IFLA_MASTER]); | |
92 | char ifname[IFNAMSIZ]; | |
93 | if (!if_indextoname(idx, ifname)) { | |
94 | strcpy(ifname, "unknown"); | |
95 | } | |
96 | printf("\tmaster=%"PRIu32" (%s)\n", idx, ifname); | |
97 | } | |
98 | ofpbuf_delete(buf); | |
99 | } | |
100 | ||
101 | nl_sock_wait(sock, POLLIN); | |
102 | poll_block(); | |
103 | } | |
104 | } | |
105 |