2 * Copyright (c) 2009, 2010, 2011, 2012 Nicira, Inc.
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
[])
42 uint64_t buf_stub
[4096 / 64];
47 set_program_name(argv
[0]);
48 vlog_set_levels(NULL
, VLF_ANY_FACILITY
, VLL_DBG
);
50 error
= nl_sock_create(NETLINK_ROUTE
, &sock
);
52 ovs_fatal(error
, "could not create rtnetlink socket");
55 error
= nl_sock_join_mcgroup(sock
, RTNLGRP_LINK
);
57 ovs_fatal(error
, "could not join RTNLGRP_LINK multicast group");
60 ofpbuf_use_stub(&buf
, buf_stub
, sizeof buf_stub
);
62 error
= nl_sock_recv(sock
, &buf
, false);
63 if (error
== EAGAIN
) {
65 } else if (error
== ENOBUFS
) {
66 ovs_error(0, "network monitor socket overflowed");
68 ovs_fatal(error
, "error on network monitor socket");
75 static const struct iff_flag flags
[] = {
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", },
94 struct nlattr
*attrs
[ARRAY_SIZE(rtnlgrp_link_policy
)];
96 struct ifinfomsg
*iim
;
99 nlh
= ofpbuf_at(&buf
, 0, NLMSG_HDRLEN
);
100 iim
= ofpbuf_at(&buf
, NLMSG_HDRLEN
, sizeof *iim
);
102 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)");
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"
120 for (i
= 0; i
< ARRAY_SIZE(flags
); i
++) {
121 if (iim
->ifi_flags
& flags
[i
].flag
) {
122 printf(" %s", flags
[i
].name
);
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");
132 printf("\tmaster=%"PRIu32
" (%s)\n", idx
, ifname
);
136 nl_sock_wait(sock
, POLLIN
);