diff -NBubrw -x '*.svn*' lib/automake.mk lib/automake.mk --- lib/automake.mk 2010-09-10 23:36:43.000000000 +0200 +++ lib/automake.mk 2011-10-07 11:18:52.000000000 +0200 @@ -187,6 +187,13 @@ lib/rtnetlink.h endif +if HAVE_IF_DL +lib_libopenvswitch_a_SOURCES += \ + lib/netdev-bsd.c \ + lib/rtbsd.c \ + lib/rtbsd.h +endif + if HAVE_OPENSSL lib_libopenvswitch_a_SOURCES += lib/stream-ssl.c nodist_lib_libopenvswitch_a_SOURCES += lib/dhparams.c diff -NBubrw -x '*.svn*' lib/netdev.c lib/netdev.c --- lib/netdev.c 2010-09-10 23:36:43.000000000 +0200 +++ lib/netdev.c 2011-10-25 16:11:14.416612232 +0200 @@ -49,6 +49,10 @@ &netdev_gre_class, &netdev_capwap_class, #endif +#ifdef __FreeBSD__ + &netdev_bsd_class, + &netdev_tap_class, +#endif }; static struct shash netdev_classes = SHASH_INITIALIZER(&netdev_classes); diff -NBubrw -x '*.svn*' lib/netdev-provider.h lib/netdev-provider.h --- lib/netdev-provider.h 2010-09-10 23:36:43.000000000 +0200 +++ lib/netdev-provider.h 2011-10-25 16:03:39.446629209 +0200 @@ -551,6 +551,9 @@ extern const struct netdev_class netdev_patch_class; extern const struct netdev_class netdev_gre_class; extern const struct netdev_class netdev_capwap_class; +#ifdef __FreeBSD__ +extern const struct netdev_class netdev_bsd_class; +#endif #ifdef __cplusplus } diff -NBubrw -x '*.svn*' lib/rtbsd.c lib/rtbsd.c --- lib/rtbsd.c 1970-01-01 01:00:00.000000000 +0100 +++ lib/rtbsd.c 2011-10-07 11:18:52.000000000 +0200 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2011 Gaetano Catalli. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "coverage.h" +#include "socket-util.h" +#include "poll-loop.h" +#include "vlog.h" +#include "rtbsd.h" + +VLOG_DEFINE_THIS_MODULE(rtbsd) + +/* PF_ROUTE socket. */ +static int notify_sock = -1; + +/* All registered notifiers. */ +static struct list all_notifiers = LIST_INITIALIZER(&all_notifiers); + +static void rtbsd_report_change(const struct if_msghdr *); +static void rtbsd_report_notify_error(void); + +/* Registers 'cb' to be called with auxiliary data 'aux' with network device + * change notifications. The notifier is stored in 'notifier', which the + * caller must not modify or free. + * + * Returns 0 if successful, otherwise a positive errno value. */ +int +rtbsd_notifier_register(struct rtbsd_notifier *notifier, + rtbsd_notify_func *cb, void *aux) +{ + if (notify_sock < 0) { + int error; + notify_sock = socket(PF_ROUTE, SOCK_RAW, 0); + if (notify_sock < 0) { + VLOG_WARN("could not create PF_ROUTE socket: %s", + strerror(errno)); + return errno; + } + error = set_nonblocking(notify_sock); + if (error) { + VLOG_WARN("error set_nonblocking PF_ROUTE socket: %s", + strerror(error)); + return error; + } + } else { + /* Catch up on notification work so that the new notifier won't + * receive any stale notifications. XXX*/ + rtbsd_notifier_run(); + } + + list_push_back(&all_notifiers, ¬ifier->node); + notifier->cb = cb; + notifier->aux = aux; + return 0; +} + +/* Cancels notification on 'notifier', which must have previously been + * registered with rtbsd_notifier_register(). */ +void +rtbsd_notifier_unregister(struct rtbsd_notifier *notifier) +{ + list_remove(¬ifier->node); + if (list_is_empty(&all_notifiers)) { + close(notify_sock); + notify_sock = -1; + } +} + +/* Calls all of the registered notifiers, passing along any as-yet-unreported + * netdev change events. */ +void +rtbsd_notifier_run(void) +{ + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + struct if_msghdr msg; + if (notify_sock < 0) { + return; + } + + for (;;) { + int retval; + + msg.ifm_type = RTM_IFINFO; + msg.ifm_version = RTM_VERSION; //XXX check if necessary + + /* read from PF_ROUTE socket */ + retval = read(notify_sock, (char *)&msg, sizeof(msg)); + if (retval >= 0) { + /* received packet from PF_ROUTE socket + * XXX check for bad packets */ + if (msg.ifm_type == RTM_IFINFO) { + rtbsd_report_change(&msg); + } + } else if (errno == EAGAIN) { + return; + } else { + if (errno == ENOBUFS) { + VLOG_WARN_RL(&rl, "PF_ROUTE receive buffer overflowed"); + } else { + VLOG_WARN_RL(&rl, "error reading PF_ROUTE socket: %s", + strerror(errno)); + } + rtbsd_report_notify_error(); + } + } +} + +/* Causes poll_block() to wake up when network device change notifications are + * ready. */ +void +rtbsd_notifier_wait(void) +{ + if (notify_sock >= 0) { + poll_fd_wait(notify_sock, POLLIN); + } +} + +static void +rtbsd_report_change(const struct if_msghdr *msg) +{ + struct rtbsd_notifier *notifier; + struct rtbsd_change change; + + /*COVERAGE_INC(rtbsd_changed);*/ /* XXX update coverage-counters.c */ + + change.msg_type = msg->ifm_type; //XXX + change.if_index = msg->ifm_index; + if_indextoname(msg->ifm_index, change.if_name); + change.master_ifindex = 0; //XXX + + LIST_FOR_EACH (notifier, struct rtbsd_notifier, node, + &all_notifiers) { + notifier->cb(&change, notifier->aux); + } +} + +/* If an error occurs the notifiers' callbacks are called with NULL changes */ +static void +rtbsd_report_notify_error(void) +{ + struct rtbsd_notifier *notifier; + + LIST_FOR_EACH (notifier, struct rtbsd_notifier, node, + &all_notifiers) { + notifier->cb(NULL, notifier->aux); + } +} diff -NBubrw -x '*.svn*' lib/rtbsd.h lib/rtbsd.h --- lib/rtbsd.h 1970-01-01 01:00:00.000000000 +0100 +++ lib/rtbsd.h 2011-10-07 11:18:52.000000000 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011 Gaetano Catalli. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND. + */ + +#ifndef RTBSD_H +#define RTBSD_H 1 + +#include "list.h" + +/* + * A digested version of a message received from a PF_ROUTE socket which + * indicates that a network device has been created or destroyed or changed. + */ +struct rtbsd_change { + /* Copied from struct if_msghdr. */ + int msg_type; /* e.g. XXX. */ + + /* Copied from struct if_msghdr. */ + int if_index; /* Index of network device. */ + + char if_name[IF_NAMESIZE]; /* Name of network device. */ + int master_ifindex; /* Ifindex of datapath master (0 if none). */ +}; + +/* + * Function called to report that a netdev has changed. 'change' describes the + * specific change. It may be null if the buffer of change information + * overflowed, in which case the function must assume that every device may + * have changed. 'aux' is as specified in the call to + * rtbsd_notifier_register(). + */ +typedef void rtbsd_notify_func(const struct rtbsd_change *, void *aux); + +struct rtbsd_notifier { + struct list node; + rtbsd_notify_func *cb; + void *aux; +}; + +int rtbsd_notifier_register(struct rtbsd_notifier *, + rtbsd_notify_func *, void *aux); +void rtbsd_notifier_unregister(struct rtbsd_notifier *); +void rtbsd_notifier_run(void); +void rtbsd_notifier_wait(void); + +#endif /* rtbsd.h */ diff -NBubrw -x '*.svn*' lib/socket-util.c lib/socket-util.c --- lib/socket-util.c 2010-09-10 23:36:43.000000000 +0200 +++ lib/socket-util.c 2011-10-07 11:18:52.000000000 +0200 @@ -259,7 +259,10 @@ } fatal_signal_add_file_to_unlink(bind_path); if (bind(fd, (struct sockaddr*) &un, un_len) - || fchmod(fd, S_IRWXU)) { +#ifndef __FreeBSD__ + || fchmod(fd, S_IRWXU) +#endif + ) { goto error; } } diff -NBubrw -x '*.svn*' lib/stream-ssl.c lib/stream-ssl.c --- lib/stream-ssl.c 2010-09-10 23:36:43.000000000 +0200 +++ lib/stream-ssl.c 2011-10-07 11:18:52.000000000 +0200 @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include diff -NBubrw -x '*.svn*' utilities/ovs-ofctl.c utilities/ovs-ofctl.c --- utilities/ovs-ofctl.c 2010-09-10 23:36:43.000000000 +0200 +++ utilities/ovs-ofctl.c 2011-10-07 11:18:59.000000000 +0200 @@ -18,6 +18,7 @@ #include #include #include +#include //XXX #include #include #include diff -NBubrw -x '*.svn*' lib/dpif-netdev.c lib/dpif-netdev.c --- lib/dpif-netdev.c 2010-09-10 23:36:43.000000000 +0200 +++ lib/dpif-netdev.c 2011-10-25 15:57:13.646643609 +0200 @@ -1043,7 +1043,7 @@ struct ofpbuf packet; struct dp_netdev *dp; - ofpbuf_init(&packet, DP_NETDEV_HEADROOM + max_mtu); + ofpbuf_init(&packet, DP_NETDEV_HEADROOM + VLAN_ETH_HEADER_LEN + max_mtu); LIST_FOR_EACH (dp, struct dp_netdev, node, &dp_netdev_list) { struct dp_netdev_port *port; --- configure.ac.orig 2010-09-14 06:49:48.000000000 +0200 +++ configure.ac 2011-11-01 11:22:52.000000000 +0100 @@ -41,6 +41,7 @@ AC_SEARCH_LIBS([pow], [m]) AC_SEARCH_LIBS([clock_gettime], [rt]) +AC_SEARCH_LIBS([timer_create], [rt]) OVS_CHECK_COVERAGE OVS_CHECK_NDEBUG @@ -52,6 +53,7 @@ OVS_CHECK_OVSDBMONITOR OVS_CHECK_ER_DIAGRAMS OVS_CHECK_IF_PACKET +OVS_CHECK_IF_DL OVS_CHECK_STRTOK_R AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec, struct stat.st_mtimensec], [], [], [[#include ]])