From: Ed Maste Date: Fri, 29 Jun 2012 21:11:24 +0000 (+0000) Subject: Route-table implementation for (Free)BSD X-Git-Tag: sliver-openvswitch-1.8.90-0~48^2~300 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=9360d9b7b50c52298c9bd47ab07b5c8c8ae074de Route-table implementation for (Free)BSD 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 Signed-off-by: Ben Pfaff --- diff --git a/acinclude.m4 b/acinclude.m4 index d33653dcb..43f044a95 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 222b50282..c89c60a1b 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 ]]) diff --git a/lib/automake.mk b/lib/automake.mk index 9d8b426ab..feac1d453 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 000000000..c14509164 --- /dev/null +++ b/lib/route-table-bsd.c @@ -0,0 +1,129 @@ +/* + * 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 + +#include "route-table.h" + +#include +#include + +#include +#include +#include +#include + +#include +#include + +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) +{ +}