]>
Commit | Line | Data |
---|---|---|
a14bc59f | 1 | /* |
e0edde6f | 2 | * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc. |
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 | 41 | { |
72d32ac0 | 42 | uint64_t buf_stub[4096 / 64]; |
064af421 | 43 | struct nl_sock *sock; |
72d32ac0 | 44 | struct ofpbuf buf; |
064af421 BP |
45 | int error; |
46 | ||
47 | set_program_name(argv[0]); | |
480ce8ab | 48 | vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG); |
064af421 | 49 | |
cceb11f5 | 50 | error = nl_sock_create(NETLINK_ROUTE, &sock); |
064af421 BP |
51 | if (error) { |
52 | ovs_fatal(error, "could not create rtnetlink socket"); | |
53 | } | |
54 | ||
cceb11f5 BP |
55 | error = nl_sock_join_mcgroup(sock, RTNLGRP_LINK); |
56 | if (error) { | |
57 | ovs_fatal(error, "could not join RTNLGRP_LINK multicast group"); | |
58 | } | |
59 | ||
72d32ac0 | 60 | ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub); |
064af421 | 61 | for (;;) { |
064af421 BP |
62 | error = nl_sock_recv(sock, &buf, false); |
63 | if (error == EAGAIN) { | |
64 | /* Nothing to do. */ | |
65 | } else if (error == ENOBUFS) { | |
66 | ovs_error(0, "network monitor socket overflowed"); | |
67 | } else if (error) { | |
68 | ovs_fatal(error, "error on network monitor socket"); | |
69 | } else { | |
d8256121 BP |
70 | struct iff_flag { |
71 | unsigned int flag; | |
72 | const char *name; | |
73 | }; | |
74 | ||
75 | static const struct iff_flag flags[] = { | |
76 | { IFF_UP, "UP", }, | |
77 | { IFF_BROADCAST, "BROADCAST", }, | |
78 | { IFF_DEBUG, "DEBUG", }, | |
79 | { IFF_LOOPBACK, "LOOPBACK", }, | |
80 | { IFF_POINTOPOINT, "POINTOPOINT", }, | |
81 | { IFF_NOTRAILERS, "NOTRAILERS", }, | |
82 | { IFF_RUNNING, "RUNNING", }, | |
83 | { IFF_NOARP, "NOARP", }, | |
84 | { IFF_PROMISC, "PROMISC", }, | |
85 | { IFF_ALLMULTI, "ALLMULTI", }, | |
86 | { IFF_MASTER, "MASTER", }, | |
87 | { IFF_SLAVE, "SLAVE", }, | |
88 | { IFF_MULTICAST, "MULTICAST", }, | |
89 | { IFF_PORTSEL, "PORTSEL", }, | |
90 | { IFF_AUTOMEDIA, "AUTOMEDIA", }, | |
91 | { IFF_DYNAMIC, "DYNAMIC", }, | |
92 | }; | |
93 | ||
064af421 BP |
94 | struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)]; |
95 | struct nlmsghdr *nlh; | |
96 | struct ifinfomsg *iim; | |
d8256121 | 97 | int i; |
064af421 | 98 | |
72d32ac0 BP |
99 | nlh = ofpbuf_at(&buf, 0, NLMSG_HDRLEN); |
100 | iim = ofpbuf_at(&buf, NLMSG_HDRLEN, sizeof *iim); | |
064af421 BP |
101 | if (!iim) { |
102 | ovs_error(0, "received bad rtnl message (no ifinfomsg)"); | |
064af421 BP |
103 | continue; |
104 | } | |
105 | ||
72d32ac0 | 106 | if (!nl_policy_parse(&buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg), |
064af421 BP |
107 | rtnlgrp_link_policy, |
108 | attrs, ARRAY_SIZE(rtnlgrp_link_policy))) { | |
109 | ovs_error(0, "received bad rtnl message (policy)"); | |
064af421 BP |
110 | continue; |
111 | } | |
112 | printf("netdev %s changed (%s):\n", | |
113 | nl_attr_get_string(attrs[IFLA_IFNAME]), | |
114 | (nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK" | |
115 | : nlh->nlmsg_type == RTM_DELLINK ? "RTM_DELLINK" | |
116 | : nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK" | |
117 | : nlh->nlmsg_type == RTM_SETLINK ? "RTM_SETLINK" | |
118 | : "other")); | |
d8256121 BP |
119 | printf("\tflags:"); |
120 | for (i = 0; i < ARRAY_SIZE(flags); i++) { | |
121 | if (iim->ifi_flags & flags[i].flag) { | |
122 | printf(" %s", flags[i].name); | |
123 | } | |
124 | } | |
125 | printf("\n"); | |
064af421 BP |
126 | if (attrs[IFLA_MASTER]) { |
127 | uint32_t idx = nl_attr_get_u32(attrs[IFLA_MASTER]); | |
128 | char ifname[IFNAMSIZ]; | |
129 | if (!if_indextoname(idx, ifname)) { | |
130 | strcpy(ifname, "unknown"); | |
131 | } | |
132 | printf("\tmaster=%"PRIu32" (%s)\n", idx, ifname); | |
133 | } | |
064af421 BP |
134 | } |
135 | ||
136 | nl_sock_wait(sock, POLLIN); | |
137 | poll_block(); | |
138 | } | |
139 | } | |
140 |