From: Ethan Jackson Date: Thu, 25 Aug 2011 21:06:54 +0000 (-0700) Subject: lib: Rename rtnetlink.[ch] files. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45c8d3a189843f0f45398caa420b952d5acd1f19;p=openvswitch lib: Rename rtnetlink.[ch] files. The only rtnetlink specific functionality contained in the rtnetlink module is the use of the NETLINK_ROUTE protocol. This can easily be passed in by callers. In preparation for generalization, this patch renames rtnetlink.[ch] to netlink-notifier.[ch]. Future patches will complete the transition. --- diff --git a/lib/automake.mk b/lib/automake.mk index 2f5b5fdf..de2b635f 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -205,11 +205,11 @@ lib_libopenvswitch_a_SOURCES += \ lib/netdev-linux.h \ lib/netdev-vport.c \ lib/netdev-vport.h \ + lib/netlink-notifier.c \ + lib/netlink-notifier.h \ lib/netlink-protocol.h \ lib/netlink-socket.c \ lib/netlink-socket.h \ - lib/rtnetlink.c \ - lib/rtnetlink.h \ lib/rtnetlink-link.c \ lib/rtnetlink-link.h \ lib/route-table.c \ diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index da48c685..88707d8d 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -39,6 +39,7 @@ #include "netdev.h" #include "netdev-linux.h" #include "netdev-vport.h" +#include "netlink-notifier.h" #include "netlink-socket.h" #include "netlink.h" #include "odp-util.h" @@ -46,7 +47,6 @@ #include "openvswitch/tunnel.h" #include "packets.h" #include "poll-loop.h" -#include "rtnetlink.h" #include "rtnetlink-link.h" #include "shash.h" #include "sset.h" diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 838dac6e..d924cf36 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -58,12 +58,12 @@ #include "netdev-provider.h" #include "netdev-vport.h" #include "netlink.h" +#include "netlink-notifier.h" #include "netlink-socket.h" #include "ofpbuf.h" #include "openflow/openflow.h" #include "packets.h" #include "poll-loop.h" -#include "rtnetlink.h" #include "rtnetlink-link.h" #include "socket-util.h" #include "shash.h" diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index df7c9a5b..15bf8bd1 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -35,13 +35,13 @@ #include "netdev-linux.h" #include "netdev-provider.h" #include "netlink.h" +#include "netlink-notifier.h" #include "netlink-socket.h" #include "ofpbuf.h" #include "openvswitch/datapath-protocol.h" #include "openvswitch/tunnel.h" #include "packets.h" #include "route-table.h" -#include "rtnetlink.h" #include "shash.h" #include "socket-util.h" #include "vlog.h" diff --git a/lib/netlink-notifier.c b/lib/netlink-notifier.c new file mode 100644 index 00000000..5635cf88 --- /dev/null +++ b/lib/netlink-notifier.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2009, 2010, 2011 Nicira Networks. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "netlink-notifier.h" + +#include +#include +#include + +#include "coverage.h" +#include "netlink.h" +#include "netlink-socket.h" +#include "ofpbuf.h" +#include "vlog.h" + +VLOG_DEFINE_THIS_MODULE(rtnetlink); + +COVERAGE_DEFINE(rtnetlink_changed); + +static void rtnetlink_report(struct rtnetlink *rtn, void *change); + +struct rtnetlink { + struct nl_sock *notify_sock; /* Rtnetlink socket. */ + struct list all_notifiers; /* All rtnetlink notifiers. */ + bool has_run; /* Guard for run and wait functions. */ + + /* Passed in by rtnetlink_create(). */ + int multicast_group; /* Multicast group we listen on. */ + rtnetlink_parse_func *parse; /* Message parsing function. */ + void *change; /* Change passed to parse. */ +}; + +/* Creates an rtnetlink handle which may be used to manage change + * notifications. The created handle will listen for rtnetlink messages on + * 'multicast_group'. Incoming messages will be parsed with 'parse' which will + * be passed 'change' as an argument. */ +struct rtnetlink * +rtnetlink_create(int multicast_group, rtnetlink_parse_func *parse, + void *change) +{ + struct rtnetlink *rtn; + + rtn = xzalloc(sizeof *rtn); + rtn->notify_sock = NULL; + rtn->multicast_group = multicast_group; + rtn->parse = parse; + rtn->change = change; + rtn->has_run = false; + + list_init(&rtn->all_notifiers); + return rtn; +} + +/* Destroys 'rtn' by freeing any memory it has reserved and closing any sockets + * it has opened. */ +void +rtnetlink_destroy(struct rtnetlink *rtn) +{ + if (rtn) { + nl_sock_destroy(rtn->notify_sock); + free(rtn); + } +} + +/* Registers 'cb' to be called with auxiliary data 'aux' with change + * notifications. The notifier is stored in 'notifier', which the caller must + * not modify or free. + * + * This is probably not the function you want. You should probably be using + * message specific notifiers like rtnetlink_link_notifier_register(). + * + * Returns 0 if successful, otherwise a positive errno value. */ +int +rtnetlink_notifier_register(struct rtnetlink *rtn, + struct rtnetlink_notifier *notifier, + rtnetlink_notify_func *cb, void *aux) +{ + if (!rtn->notify_sock) { + struct nl_sock *sock; + int error; + + error = nl_sock_create(NETLINK_ROUTE, &sock); + if (!error) { + error = nl_sock_join_mcgroup(sock, rtn->multicast_group); + } + if (error) { + nl_sock_destroy(sock); + VLOG_WARN("could not create rtnetlink socket: %s", + strerror(error)); + return error; + } + rtn->notify_sock = sock; + } else { + /* Catch up on notification work so that the new notifier won't + * receive any stale notifications. */ + rtnetlink_notifier_run(rtn); + } + + list_push_back(&rtn->all_notifiers, ¬ifier->node); + notifier->cb = cb; + notifier->aux = aux; + return 0; +} + +/* Cancels notification on 'notifier', which must have previously been + * registered with rtnetlink_notifier_register(). */ +void +rtnetlink_notifier_unregister(struct rtnetlink *rtn, + struct rtnetlink_notifier *notifier) +{ + list_remove(¬ifier->node); + if (list_is_empty(&rtn->all_notifiers)) { + nl_sock_destroy(rtn->notify_sock); + rtn->notify_sock = NULL; + } +} + +/* Calls all of the registered notifiers, passing along any as-yet-unreported + * change events. */ +void +rtnetlink_notifier_run(struct rtnetlink *rtn) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + + if (!rtn->notify_sock || rtn->has_run) { + return; + } + + rtn->has_run = true; + for (;;) { + struct ofpbuf *buf; + int error; + + error = nl_sock_recv(rtn->notify_sock, &buf, false); + if (!error) { + if (rtn->parse(buf, rtn->change)) { + rtnetlink_report(rtn, rtn->change); + } else { + VLOG_WARN_RL(&rl, "received bad rtnl message"); + rtnetlink_report(rtn, NULL); + } + ofpbuf_delete(buf); + } else if (error == EAGAIN) { + return; + } else { + if (error == ENOBUFS) { + VLOG_WARN_RL(&rl, "rtnetlink receive buffer overflowed"); + } else { + VLOG_WARN_RL(&rl, "error reading rtnetlink socket: %s", + strerror(error)); + } + rtnetlink_report(rtn, NULL); + } + } +} + +/* Causes poll_block() to wake up when change notifications are ready. */ +void +rtnetlink_notifier_wait(struct rtnetlink *rtn) +{ + rtn->has_run = false; + if (rtn->notify_sock) { + nl_sock_wait(rtn->notify_sock, POLLIN); + } +} + +static void +rtnetlink_report(struct rtnetlink *rtn, void *change) +{ + struct rtnetlink_notifier *notifier; + + if (change) { + COVERAGE_INC(rtnetlink_changed); + } + + LIST_FOR_EACH (notifier, node, &rtn->all_notifiers) { + notifier->cb(change, notifier->aux); + } +} + diff --git a/lib/netlink-notifier.h b/lib/netlink-notifier.h new file mode 100644 index 00000000..8d6f2bb1 --- /dev/null +++ b/lib/netlink-notifier.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2009 Nicira Networks. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RTNETLINK_H +#define RTNETLINK_H 1 + +/* These functions are Linux specific, so they should be used directly only by + * Linux-specific code. */ + +#include "list.h" + +struct rtnetlink; +struct nlattr; +struct ofpbuf; + +/* Function called to report rtnetlink notifications. 'change' describes the + * specific change filled out by an rtnetlink_parse_func. It may be null if + * the buffer of change information overflowed, in which case the function must + * assume that everything may have changed. 'aux' is as specified in + * rtnetlink_notifier_register(). + */ +typedef void rtnetlink_notify_func(const void *change, void *aux); + +/* Function called to parse incoming rtnetlink notifications. The 'buf' + * message should be parsed into 'change' as specified in rtnetlink_create(). + */ +typedef bool rtnetlink_parse_func(struct ofpbuf *buf, void *change); + +struct rtnetlink_notifier { + struct list node; + rtnetlink_notify_func *cb; + void *aux; +}; + +struct rtnetlink *rtnetlink_create(int multicast_group, + rtnetlink_parse_func *, + void *change); +void rtnetlink_destroy(struct rtnetlink *rtn); +int rtnetlink_notifier_register(struct rtnetlink *, + struct rtnetlink_notifier *, + rtnetlink_notify_func *, void *aux); +void rtnetlink_notifier_unregister(struct rtnetlink *, + struct rtnetlink_notifier *); +void rtnetlink_notifier_run(struct rtnetlink *); +void rtnetlink_notifier_wait(struct rtnetlink *); +#endif /* rtnetlink.h */ diff --git a/lib/route-table.c b/lib/route-table.c index 8212c546..22d12f7a 100644 --- a/lib/route-table.c +++ b/lib/route-table.c @@ -27,9 +27,9 @@ #include "hash.h" #include "hmap.h" #include "netlink.h" +#include "netlink-notifier.h" #include "netlink-socket.h" #include "ofpbuf.h" -#include "rtnetlink.h" #include "rtnetlink-link.h" #include "vlog.h" diff --git a/lib/rtnetlink-link.c b/lib/rtnetlink-link.c index 98ab3991..75035858 100644 --- a/lib/rtnetlink-link.c +++ b/lib/rtnetlink-link.c @@ -23,8 +23,8 @@ #include #include "netlink.h" +#include "netlink-notifier.h" #include "ofpbuf.h" -#include "rtnetlink.h" static struct rtnetlink *rtn = NULL; static struct rtnetlink_link_change rtn_change; diff --git a/lib/rtnetlink.c b/lib/rtnetlink.c deleted file mode 100644 index b6005543..00000000 --- a/lib/rtnetlink.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2009, 2010, 2011 Nicira Networks. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "rtnetlink.h" - -#include -#include -#include - -#include "coverage.h" -#include "netlink.h" -#include "netlink-socket.h" -#include "ofpbuf.h" -#include "vlog.h" - -VLOG_DEFINE_THIS_MODULE(rtnetlink); - -COVERAGE_DEFINE(rtnetlink_changed); - -static void rtnetlink_report(struct rtnetlink *rtn, void *change); - -struct rtnetlink { - struct nl_sock *notify_sock; /* Rtnetlink socket. */ - struct list all_notifiers; /* All rtnetlink notifiers. */ - bool has_run; /* Guard for run and wait functions. */ - - /* Passed in by rtnetlink_create(). */ - int multicast_group; /* Multicast group we listen on. */ - rtnetlink_parse_func *parse; /* Message parsing function. */ - void *change; /* Change passed to parse. */ -}; - -/* Creates an rtnetlink handle which may be used to manage change - * notifications. The created handle will listen for rtnetlink messages on - * 'multicast_group'. Incoming messages will be parsed with 'parse' which will - * be passed 'change' as an argument. */ -struct rtnetlink * -rtnetlink_create(int multicast_group, rtnetlink_parse_func *parse, - void *change) -{ - struct rtnetlink *rtn; - - rtn = xzalloc(sizeof *rtn); - rtn->notify_sock = NULL; - rtn->multicast_group = multicast_group; - rtn->parse = parse; - rtn->change = change; - rtn->has_run = false; - - list_init(&rtn->all_notifiers); - return rtn; -} - -/* Destroys 'rtn' by freeing any memory it has reserved and closing any sockets - * it has opened. */ -void -rtnetlink_destroy(struct rtnetlink *rtn) -{ - if (rtn) { - nl_sock_destroy(rtn->notify_sock); - free(rtn); - } -} - -/* Registers 'cb' to be called with auxiliary data 'aux' with change - * notifications. The notifier is stored in 'notifier', which the caller must - * not modify or free. - * - * This is probably not the function you want. You should probably be using - * message specific notifiers like rtnetlink_link_notifier_register(). - * - * Returns 0 if successful, otherwise a positive errno value. */ -int -rtnetlink_notifier_register(struct rtnetlink *rtn, - struct rtnetlink_notifier *notifier, - rtnetlink_notify_func *cb, void *aux) -{ - if (!rtn->notify_sock) { - struct nl_sock *sock; - int error; - - error = nl_sock_create(NETLINK_ROUTE, &sock); - if (!error) { - error = nl_sock_join_mcgroup(sock, rtn->multicast_group); - } - if (error) { - nl_sock_destroy(sock); - VLOG_WARN("could not create rtnetlink socket: %s", - strerror(error)); - return error; - } - rtn->notify_sock = sock; - } else { - /* Catch up on notification work so that the new notifier won't - * receive any stale notifications. */ - rtnetlink_notifier_run(rtn); - } - - list_push_back(&rtn->all_notifiers, ¬ifier->node); - notifier->cb = cb; - notifier->aux = aux; - return 0; -} - -/* Cancels notification on 'notifier', which must have previously been - * registered with rtnetlink_notifier_register(). */ -void -rtnetlink_notifier_unregister(struct rtnetlink *rtn, - struct rtnetlink_notifier *notifier) -{ - list_remove(¬ifier->node); - if (list_is_empty(&rtn->all_notifiers)) { - nl_sock_destroy(rtn->notify_sock); - rtn->notify_sock = NULL; - } -} - -/* Calls all of the registered notifiers, passing along any as-yet-unreported - * change events. */ -void -rtnetlink_notifier_run(struct rtnetlink *rtn) -{ - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); - - if (!rtn->notify_sock || rtn->has_run) { - return; - } - - rtn->has_run = true; - for (;;) { - struct ofpbuf *buf; - int error; - - error = nl_sock_recv(rtn->notify_sock, &buf, false); - if (!error) { - if (rtn->parse(buf, rtn->change)) { - rtnetlink_report(rtn, rtn->change); - } else { - VLOG_WARN_RL(&rl, "received bad rtnl message"); - rtnetlink_report(rtn, NULL); - } - ofpbuf_delete(buf); - } else if (error == EAGAIN) { - return; - } else { - if (error == ENOBUFS) { - VLOG_WARN_RL(&rl, "rtnetlink receive buffer overflowed"); - } else { - VLOG_WARN_RL(&rl, "error reading rtnetlink socket: %s", - strerror(error)); - } - rtnetlink_report(rtn, NULL); - } - } -} - -/* Causes poll_block() to wake up when change notifications are ready. */ -void -rtnetlink_notifier_wait(struct rtnetlink *rtn) -{ - rtn->has_run = false; - if (rtn->notify_sock) { - nl_sock_wait(rtn->notify_sock, POLLIN); - } -} - -static void -rtnetlink_report(struct rtnetlink *rtn, void *change) -{ - struct rtnetlink_notifier *notifier; - - if (change) { - COVERAGE_INC(rtnetlink_changed); - } - - LIST_FOR_EACH (notifier, node, &rtn->all_notifiers) { - notifier->cb(change, notifier->aux); - } -} - diff --git a/lib/rtnetlink.h b/lib/rtnetlink.h deleted file mode 100644 index 8d6f2bb1..00000000 --- a/lib/rtnetlink.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2009 Nicira Networks. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef RTNETLINK_H -#define RTNETLINK_H 1 - -/* These functions are Linux specific, so they should be used directly only by - * Linux-specific code. */ - -#include "list.h" - -struct rtnetlink; -struct nlattr; -struct ofpbuf; - -/* Function called to report rtnetlink notifications. 'change' describes the - * specific change filled out by an rtnetlink_parse_func. It may be null if - * the buffer of change information overflowed, in which case the function must - * assume that everything may have changed. 'aux' is as specified in - * rtnetlink_notifier_register(). - */ -typedef void rtnetlink_notify_func(const void *change, void *aux); - -/* Function called to parse incoming rtnetlink notifications. The 'buf' - * message should be parsed into 'change' as specified in rtnetlink_create(). - */ -typedef bool rtnetlink_parse_func(struct ofpbuf *buf, void *change); - -struct rtnetlink_notifier { - struct list node; - rtnetlink_notify_func *cb; - void *aux; -}; - -struct rtnetlink *rtnetlink_create(int multicast_group, - rtnetlink_parse_func *, - void *change); -void rtnetlink_destroy(struct rtnetlink *rtn); -int rtnetlink_notifier_register(struct rtnetlink *, - struct rtnetlink_notifier *, - rtnetlink_notify_func *, void *aux); -void rtnetlink_notifier_unregister(struct rtnetlink *, - struct rtnetlink_notifier *); -void rtnetlink_notifier_run(struct rtnetlink *); -void rtnetlink_notifier_wait(struct rtnetlink *); -#endif /* rtnetlink.h */ diff --git a/vswitchd/ovs-brcompatd.c b/vswitchd/ovs-brcompatd.c index c88684f9..f42f01b4 100644 --- a/vswitchd/ovs-brcompatd.c +++ b/vswitchd/ovs-brcompatd.c @@ -43,13 +43,13 @@ #include "leak-checker.h" #include "netdev.h" #include "netlink.h" +#include "netlink-notifier.h" #include "netlink-socket.h" #include "ofpbuf.h" #include "openvswitch/brcompat-netlink.h" #include "packets.h" #include "poll-loop.h" #include "process.h" -#include "rtnetlink.h" #include "rtnetlink-link.h" #include "signals.h" #include "sset.h"