]>
Commit | Line | Data |
---|---|---|
9360d9b7 EM |
1 | /* |
2 | * Copyright (c) 2012 Ed Maste. All rights reserved. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | ||
19 | #include "route-table.h" | |
20 | ||
21 | #include <sys/socket.h> | |
22 | #include <sys/types.h> | |
23 | ||
24 | #include <net/if.h> | |
25 | #include <net/route.h> | |
26 | #include <net/if_dl.h> | |
27 | #include <netinet/in.h> | |
28 | ||
29 | #include <string.h> | |
30 | #include <unistd.h> | |
31 | ||
2d2b28d5 | 32 | #include "ovs-router.h" |
36673528 | 33 | #include "packets.h" |
43e2a621 | 34 | #include "openvswitch/vlog.h" |
e29915b2 | 35 | #include "util.h" |
9360d9b7 | 36 | |
36673528 YT |
37 | VLOG_DEFINE_THIS_MODULE(route_table_bsd); |
38 | ||
9360d9b7 | 39 | bool |
88ffdc93 | 40 | route_table_fallback_lookup(ovs_be32 ip, char name[], ovs_be32 *gw) |
9360d9b7 EM |
41 | { |
42 | struct { | |
43 | struct rt_msghdr rtm; | |
44 | char space[512]; | |
45 | } rtmsg; | |
46 | ||
47 | struct rt_msghdr *rtm = &rtmsg.rtm; | |
48 | struct sockaddr_dl *ifp = NULL; | |
49 | struct sockaddr_in *sin; | |
50 | struct sockaddr *sa; | |
51 | static int seq; | |
52 | int i, len, namelen, rtsock; | |
6595fb00 | 53 | const pid_t pid = getpid(); |
a7701e29 | 54 | bool got_ifp = false; |
9360d9b7 EM |
55 | |
56 | rtsock = socket(PF_ROUTE, SOCK_RAW, 0); | |
57 | if (rtsock < 0) | |
58 | return false; | |
59 | ||
60 | memset(&rtmsg, 0, sizeof(rtmsg)); | |
61 | ||
62 | rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in); | |
63 | rtm->rtm_version = RTM_VERSION; | |
64 | rtm->rtm_type = RTM_GET; | |
65 | rtm->rtm_addrs = RTA_DST | RTA_IFP; | |
66 | rtm->rtm_seq = ++seq; | |
67 | ||
68 | sin = (struct sockaddr_in *)(rtm + 1); | |
69 | sin->sin_len = len = sizeof(struct sockaddr_in); | |
70 | sin->sin_family = AF_INET; | |
71 | sin->sin_addr.s_addr = ip; | |
72 | ||
73 | if ((write(rtsock, (char *)&rtmsg, rtm->rtm_msglen)) < 0) { | |
74 | close(rtsock); | |
75 | return false; | |
76 | } | |
77 | ||
36673528 YT |
78 | VLOG_DBG("looking route up for " IP_FMT " pid %" PRIuMAX, |
79 | IP_ARGS(ip), (uintmax_t)pid); | |
9360d9b7 EM |
80 | do { |
81 | len = read(rtsock, (char *)&rtmsg, sizeof(rtmsg)); | |
36673528 YT |
82 | if (len > 0) { |
83 | VLOG_DBG("got rtmsg pid %" PRIuMAX " seq %d", | |
84 | (uintmax_t)rtmsg.rtm.rtm_pid, | |
85 | rtmsg.rtm.rtm_seq); | |
86 | } | |
9360d9b7 EM |
87 | } while (len > 0 && (rtmsg.rtm.rtm_seq != seq || |
88 | rtmsg.rtm.rtm_pid != pid)); | |
89 | ||
90 | close(rtsock); | |
91 | ||
92 | if (len < 0) { | |
93 | return false; | |
94 | } | |
95 | ||
a7701e29 | 96 | *gw = 0; |
9360d9b7 EM |
97 | sa = (struct sockaddr *)(rtm + 1); |
98 | for (i = 1; i; i <<= 1) { | |
99 | if (rtm->rtm_addrs & i) { | |
100 | if (i == RTA_IFP && sa->sa_family == AF_LINK && | |
e29915b2 YT |
101 | ALIGNED_CAST(struct sockaddr_dl *, sa)->sdl_nlen) { |
102 | ifp = ALIGNED_CAST(struct sockaddr_dl *, sa); | |
9360d9b7 EM |
103 | namelen = ifp->sdl_nlen; |
104 | if (namelen > IFNAMSIZ - 1) | |
105 | namelen = IFNAMSIZ - 1; | |
106 | memcpy(name, ifp->sdl_data, namelen); | |
107 | name[namelen] = '\0'; | |
36673528 | 108 | VLOG_DBG("got ifp %s", name); |
a7701e29 YT |
109 | got_ifp = true; |
110 | } else if (i == RTA_GATEWAY && sa->sa_family == AF_INET) { | |
111 | const struct sockaddr_in *sin_dst = | |
112 | ALIGNED_CAST(struct sockaddr_in *, sa); | |
113 | ||
114 | *gw = sin_dst->sin_addr.s_addr; | |
36673528 | 115 | VLOG_DBG("got gateway " IP_FMT, IP_ARGS(*gw)); |
9360d9b7 | 116 | } |
339f0a19 | 117 | #if defined(__FreeBSD__) |
9360d9b7 | 118 | sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa)); |
339f0a19 YT |
119 | #elif defined(__NetBSD__) |
120 | sa = (struct sockaddr *)((char *)sa + RT_ROUNDUP(sa->sa_len)); | |
121 | #else | |
122 | #error unimplemented | |
123 | #endif | |
9360d9b7 EM |
124 | } |
125 | } | |
a7701e29 | 126 | return got_ifp; |
9360d9b7 EM |
127 | } |
128 | ||
41ca1e0a AW |
129 | uint64_t |
130 | route_table_get_change_seq(void) | |
131 | { | |
132 | return 0; | |
133 | } | |
134 | ||
9360d9b7 | 135 | void |
b772066f | 136 | route_table_init(void) |
9360d9b7 | 137 | { |
88ffdc93 | 138 | ovs_router_init(); |
9360d9b7 EM |
139 | } |
140 | ||
141 | void | |
142 | route_table_run(void) | |
143 | { | |
144 | } | |
145 | ||
146 | void | |
147 | route_table_wait(void) | |
148 | { | |
149 | } |