This is a trivial implementation of the route-table functionality for FreeBSD, as needed by ofproto/ofproto-dpif-sflow.c. It has not yet been extensively tested.
Signed-off-by: Ed Maste <ema...@freebsd.org> --- Note that my primary goal here was to get a basic implementation to allow it to build, so that I can move on to other work for the time being. If performance or functionality is an issue I'll revisit this. The autoconf changes are based on the patch that Giuseppe posted recently. acinclude.m4 | 11 ++++ configure.ac | 1 + lib/automake.mk | 5 ++ lib/route-table-bsd.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 lib/route-table-bsd.c diff --git a/acinclude.m4 b/acinclude.m4 index d33653d..43f044a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -287,6 +287,17 @@ AC_DEFUN([OVS_CHECK_IF_PACKET], [Define to 1 if net/if_packet.h is available.]) fi]) +dnl Checks for net/if_dl.h +AC_DEFUN([OVS_CHECK_IF_DL], + [AC_CHECK_HEADER([net/if_dl.h], + [HAVE_IF_DL=yes], + [HAVE_IF_DL=no]) + AM_CONDITIONAL([HAVE_IF_DL], [test "$HAVE_IF_DL" = yes]) + if test "$HAVE_IF_DL" = yes; then + AC_DEFINE([HAVE_IF_DL], [1], + [Define to 1 if net/if_dl.h is available.]) + fi]) + dnl Checks for buggy strtok_r. dnl dnl Some versions of glibc 2.7 has a bug in strtok_r when compiling diff --git a/configure.ac b/configure.ac index 222b502..c89c60a 100644 --- a/configure.ac +++ b/configure.ac @@ -52,6 +52,7 @@ OVS_CHECK_PYUIC4 OVS_CHECK_OVSDBMONITOR OVS_CHECK_DOT 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 <sys/stat.h>]]) diff --git a/lib/automake.mk b/lib/automake.mk index 9d8b426..feac1d4 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -238,6 +238,11 @@ lib_libopenvswitch_a_SOURCES += \ lib/route-table.h endif +if HAVE_IF_DL +lib_libopenvswitch_a_SOURCES += \ + lib/route-table-bsd.c +endif + if HAVE_OPENSSL lib_libopenvswitch_a_SOURCES += lib/stream-ssl.c nodist_lib_libopenvswitch_a_SOURCES += lib/dhparams.c diff --git a/lib/route-table-bsd.c b/lib/route-table-bsd.c new file mode 100644 index 0000000..8b6cb6c --- /dev/null +++ b/lib/route-table-bsd.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2012 Ed Maste. All rights reserved. + * + * 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 <config.h> + +#include "route-table.h" + +#include <sys/socket.h> +#include <sys/types.h> + +#include <net/if.h> +#include <net/route.h> +#include <net/if_dl.h> +#include <netinet/in.h> + +#include <string.h> +#include <unistd.h> + +VLOG_DEFINE_THIS_MODULE(route_table); + +static int pid; +static unsigned int register_count = 0; + +bool +route_table_get_name(ovs_be32 ip, char name[IFNAMSIZ]) +{ + struct { + struct rt_msghdr rtm; + char space[512]; + } rtmsg; + + struct rt_msghdr *rtm = &rtmsg.rtm; + struct sockaddr_dl *ifp = NULL; + struct sockaddr_in *sin; + struct sockaddr *sa; + static int seq; + int i, len, namelen, rtsock; + + rtsock = socket(PF_ROUTE, SOCK_RAW, 0); + if (rtsock < 0) + return false; + + memset(&rtmsg, 0, sizeof(rtmsg)); + + rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); + rtm->rtm_version = RTM_VERSION; + rtm->rtm_type = RTM_GET; + rtm->rtm_addrs = RTA_DST | RTA_IFP; + rtm->rtm_seq = ++seq; + + sin = (struct sockaddr_in *)(rtm + 1); + sin->sin_len = len = sizeof(struct sockaddr_in); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = ip; + + if ((write(rtsock, (char *)&rtmsg, rtm->rtm_msglen)) < 0) { + close(rtsock); + return false; + } + + do { + len = read(rtsock, (char *)&rtmsg, sizeof(rtmsg)); + } while (len > 0 && (rtmsg.rtm.rtm_seq != seq || + rtmsg.rtm.rtm_pid != pid)); + + close(rtsock); + + if (len < 0) { + return false; + } + + sa = (struct sockaddr *)(rtm + 1); + for (i = 1; i; i <<= 1) { + if (rtm->rtm_addrs & i) { + if (i == RTA_IFP && sa->sa_family == AF_LINK && + ((struct sockaddr_dl *)sa)->sdl_nlen) { + ifp = (struct sockaddr_dl *)sa; + namelen = ifp->sdl_nlen; + if (namelen > IFNAMSIZ - 1) + namelen = IFNAMSIZ - 1; + memcpy(name, ifp->sdl_data, namelen); + name[namelen] = '\0'; + return true; + } + sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa)); + } + } + return false; +} + +void +route_table_register() +{ + if (!register_count) + { + pid = getpid(); + } + + register_count++; +} + +void +route_table_unregister() +{ + register_count--; +} + +void +route_table_run(void) +{ +} + +void +route_table_wait(void) +{ +} -- 1.7.10.3 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev