2 * Copyright (c) 2009, 2010, 2011, 2012 Nicira Networks.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <sys/socket.h>
25 #include <linux/rtnetlink.h>
27 #include "netlink-socket.h"
29 #include "poll-loop.h"
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 },
40 main(int argc OVS_UNUSED, char *argv[])
45 set_program_name(argv[0]);
46 vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG);
48 error = nl_sock_create(NETLINK_ROUTE, &sock);
50 ovs_fatal(error, "could not create rtnetlink socket");
53 error = nl_sock_join_mcgroup(sock, RTNLGRP_LINK);
55 ovs_fatal(error, "could not join RTNLGRP_LINK multicast group");
61 error = nl_sock_recv(sock, &buf, false);
62 if (error == EAGAIN) {
64 } else if (error == ENOBUFS) {
65 ovs_error(0, "network monitor socket overflowed");
67 ovs_fatal(error, "error on network monitor socket");
74 static const struct iff_flag flags[] = {
76 { IFF_BROADCAST, "BROADCAST", },
77 { IFF_DEBUG, "DEBUG", },
78 { IFF_LOOPBACK, "LOOPBACK", },
79 { IFF_POINTOPOINT, "POINTOPOINT", },
80 { IFF_NOTRAILERS, "NOTRAILERS", },
81 { IFF_RUNNING, "RUNNING", },
82 { IFF_NOARP, "NOARP", },
83 { IFF_PROMISC, "PROMISC", },
84 { IFF_ALLMULTI, "ALLMULTI", },
85 { IFF_MASTER, "MASTER", },
86 { IFF_SLAVE, "SLAVE", },
87 { IFF_MULTICAST, "MULTICAST", },
88 { IFF_PORTSEL, "PORTSEL", },
89 { IFF_AUTOMEDIA, "AUTOMEDIA", },
90 { IFF_DYNAMIC, "DYNAMIC", },
93 struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)];
95 struct ifinfomsg *iim;
98 nlh = ofpbuf_at(buf, 0, NLMSG_HDRLEN);
99 iim = ofpbuf_at(buf, NLMSG_HDRLEN, sizeof *iim);
101 ovs_error(0, "received bad rtnl message (no ifinfomsg)");
106 if (!nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg),
108 attrs, ARRAY_SIZE(rtnlgrp_link_policy))) {
109 ovs_error(0, "received bad rtnl message (policy)");
113 printf("netdev %s changed (%s):\n",
114 nl_attr_get_string(attrs[IFLA_IFNAME]),
115 (nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK"
116 : nlh->nlmsg_type == RTM_DELLINK ? "RTM_DELLINK"
117 : nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK"
118 : nlh->nlmsg_type == RTM_SETLINK ? "RTM_SETLINK"
121 for (i = 0; i < ARRAY_SIZE(flags); i++) {
122 if (iim->ifi_flags & flags[i].flag) {
123 printf(" %s", flags[i].name);
127 if (attrs[IFLA_MASTER]) {
128 uint32_t idx = nl_attr_get_u32(attrs[IFLA_MASTER]);
129 char ifname[IFNAMSIZ];
130 if (!if_indextoname(idx, ifname)) {
131 strcpy(ifname, "unknown");
133 printf("\tmaster=%"PRIu32" (%s)\n", idx, ifname);
138 nl_sock_wait(sock, POLLIN);