aboutsummaryrefslogtreecommitdiff
path: root/lib/route-table-bsd.c
diff options
context:
space:
mode:
authorEd Maste <emaste@freebsd.org>2012-06-29 21:11:24 +0000
committerBen Pfaff <blp@nicira.com>2012-06-29 14:42:38 -0700
commit9360d9b7b50c52298c9bd47ab07b5c8c8ae074de (patch)
tree7fbe3d92708e193071c080967792384dd0d647bb /lib/route-table-bsd.c
parent55abbe6977a15890b787ed35378d0f168384799b (diff)
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 <emaste@freebsd.org> Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/route-table-bsd.c')
-rw-r--r--lib/route-table-bsd.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/lib/route-table-bsd.c b/lib/route-table-bsd.c
new file mode 100644
index 00000000..c1450916
--- /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 <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)
+{
+}