]> git.proxmox.com Git - ovs.git/blob - utilities/nlmon.c
ofproto-dpif: Implement PACKET_IN in userspace.
[ovs.git] / utilities / nlmon.c
1 /*
2 * Copyright (c) 2009, 2010, 2011 Nicira Networks.
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
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"
27 #include "netlink-socket.h"
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
40 main(int argc OVS_UNUSED, char *argv[])
41 {
42 struct nl_sock *sock;
43 int error;
44
45 set_program_name(argv[0]);
46 vlog_set_levels(NULL, VLF_ANY_FACILITY, VLL_DBG);
47
48 error = nl_sock_create(NETLINK_ROUTE, &sock);
49 if (error) {
50 ovs_fatal(error, "could not create rtnetlink socket");
51 }
52
53 error = nl_sock_join_mcgroup(sock, RTNLGRP_LINK);
54 if (error) {
55 ovs_fatal(error, "could not join RTNLGRP_LINK multicast group");
56 }
57
58 for (;;) {
59 struct ofpbuf *buf;
60
61 error = nl_sock_recv(sock, &buf, false);
62 if (error == EAGAIN) {
63 /* Nothing to do. */
64 } else if (error == ENOBUFS) {
65 ovs_error(0, "network monitor socket overflowed");
66 } else if (error) {
67 ovs_fatal(error, "error on network monitor socket");
68 } else {
69 struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)];
70 struct nlmsghdr *nlh;
71 struct ifinfomsg *iim;
72
73 nlh = ofpbuf_at(buf, 0, NLMSG_HDRLEN);
74 iim = ofpbuf_at(buf, NLMSG_HDRLEN, sizeof *iim);
75 if (!iim) {
76 ovs_error(0, "received bad rtnl message (no ifinfomsg)");
77 ofpbuf_delete(buf);
78 continue;
79 }
80
81 if (!nl_policy_parse(buf, NLMSG_HDRLEN + sizeof(struct ifinfomsg),
82 rtnlgrp_link_policy,
83 attrs, ARRAY_SIZE(rtnlgrp_link_policy))) {
84 ovs_error(0, "received bad rtnl message (policy)");
85 ofpbuf_delete(buf);
86 continue;
87 }
88 printf("netdev %s changed (%s):\n",
89 nl_attr_get_string(attrs[IFLA_IFNAME]),
90 (nlh->nlmsg_type == RTM_NEWLINK ? "RTM_NEWLINK"
91 : nlh->nlmsg_type == RTM_DELLINK ? "RTM_DELLINK"
92 : nlh->nlmsg_type == RTM_GETLINK ? "RTM_GETLINK"
93 : nlh->nlmsg_type == RTM_SETLINK ? "RTM_SETLINK"
94 : "other"));
95 if (attrs[IFLA_MASTER]) {
96 uint32_t idx = nl_attr_get_u32(attrs[IFLA_MASTER]);
97 char ifname[IFNAMSIZ];
98 if (!if_indextoname(idx, ifname)) {
99 strcpy(ifname, "unknown");
100 }
101 printf("\tmaster=%"PRIu32" (%s)\n", idx, ifname);
102 }
103 ofpbuf_delete(buf);
104 }
105
106 nl_sock_wait(sock, POLLIN);
107 poll_block();
108 }
109 }
110