1 /* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
4 * We are making the OpenFlow specification and associated documentation
5 * (Software) available for public use and benefit with the expectation
6 * that others will use, modify and enhance the Software and contribute
7 * those enhancements back to the community. However, since we would
8 * like to make the Software available for broadest use, with as few
9 * restrictions as possible permission is hereby granted, free of
10 * charge, to any person obtaining a copy of this Software to deal in
11 * the Software under the copyrights without restriction, including
12 * without limitation the rights to use, copy, modify, merge, publish,
13 * distribute, sublicense, and/or sell copies of the Software, and to
14 * permit persons to whom the Software is furnished to do so, subject to
15 * the following conditions:
17 * The above copyright notice and this permission notice shall be
18 * included in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
24 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
25 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 * The name and trademarks of copyright holder(s) may NOT be used in
30 * advertising or publicity pertaining to the Software or any
31 * derivatives without specific, written prior permission.
35 #include <arpa/inet.h>
42 #include "controller.h"
47 #include "poll-loop.h"
51 #define THIS_MODULE VLM_datapath
54 #define BRIDGE_PORT_NO_FLOOD 0x00000001
56 static void send_port_status(struct sw_port *p, uint8_t status);
57 static void del_switch_port(struct sw_port *p);
58 static int port_no(struct datapath *dp, struct sw_port *p)
60 assert(p >= dp->ports && p < &dp->ports[ARRAY_SIZE(dp->ports)]);
64 /* Generates a unique datapath id. It incorporates the datapath index
65 * and a hardware address, if available. If not, it generates a random
71 /* Choose a random datapath id. */
77 for (i = 0; i < ETH_ADDR_LEN; i++) {
78 id |= (uint64_t)(rand() & 0xff) << (8*(ETH_ADDR_LEN-1 - i));
85 dp_new(struct datapath **dp_, uint64_t dpid, struct controller_connection *cc)
89 dp = calloc(1, sizeof *dp);
94 dp->last_timeout = time(0);
96 dp->id = dpid <= UINT64_C(0xffffffffffff) ? dpid : gen_datapath_id();
97 dp->chain = chain_create();
99 VLOG_ERR("could not create chain");
104 list_init(&dp->port_list);
105 dp->miss_send_len = OFP_DEFAULT_MISS_SEND_LEN;
111 dp_add_port(struct datapath *dp, const char *name)
113 struct netdev *netdev;
117 error = netdev_open(name, &netdev);
122 for (p = dp->ports; ; p++) {
123 if (p >= &dp->ports[ARRAY_SIZE(dp->ports)]) {
125 } else if (!p->netdev) {
132 list_push_back(&dp->port_list, &p->node);
134 /* Notify the ctlpath that this port has been added */
135 send_port_status(p, OFPPR_ADD);
141 dp_run(struct datapath *dp)
143 time_t now = time(0);
144 struct sw_port *p, *n;
145 struct buffer *buffer = NULL;
147 if (now != dp->last_timeout) {
148 chain_timeout(dp->chain, dp);
149 dp->last_timeout = now;
151 poll_timer_wait(1000);
153 LIST_FOR_EACH_SAFE (p, n, struct sw_port, node, &dp->port_list) {
157 /* Allocate buffer with some headroom to add headers in forwarding
158 * to the controller or adding a vlan tag, plus an extra 2 bytes to
159 * allow IP headers to be aligned on a 4-byte boundary. */
160 const int headroom = 128 + 2;
161 buffer = buffer_new(ETH_TOTAL_MAX + headroom);
162 buffer->data += headroom;
164 error = netdev_recv(p->netdev, buffer, false);
166 fwd_port_input(dp, buffer, port_no(dp, p));
168 } else if (error != EAGAIN) {
169 VLOG_ERR("Error receiving data from %s: %s",
170 netdev_get_name(p->netdev), strerror(error));
174 buffer_delete(buffer);
178 dp_wait(struct datapath *dp)
182 LIST_FOR_EACH (p, struct sw_port, node, &dp->port_list) {
183 poll_fd_wait(netdev_get_fd(p->netdev), POLLIN, NULL);
187 /* Delete 'p' from switch. */
189 del_switch_port(struct sw_port *p)
191 send_port_status(p, OFPPR_DELETE);
192 netdev_close(p->netdev);
194 list_remove(&p->node);
198 dp_destroy(struct datapath *dp)
200 struct sw_port *p, *n;
206 LIST_FOR_EACH_SAFE (p, n, struct sw_port, node, &dp->port_list) {
209 chain_destroy(dp->chain);
214 flood(struct datapath *dp, struct buffer *buffer, int in_port)
217 struct sw_port *prev_port;
220 LIST_FOR_EACH (p, struct sw_port, node, &dp->port_list) {
221 if (port_no(dp, p) == in_port || p->flags & BRIDGE_PORT_NO_FLOOD) {
225 struct buffer *clone = buffer_clone(buffer);
227 buffer_delete(buffer);
230 dp_output_port(dp, clone, in_port, port_no(dp, prev_port));
235 dp_output_port(dp, buffer, in_port, port_no(dp, prev_port));
237 buffer_delete(buffer);
243 output_packet(struct datapath *dp, struct buffer *buffer, int out_port)
245 if (out_port >= 0 && out_port < OFPP_MAX) {
246 struct sw_port *p = &dp->ports[out_port];
247 if (p->netdev != NULL) {
248 /* FIXME: queue packets. */
249 netdev_send(p->netdev, buffer, false);
254 buffer_delete(buffer);
255 /* FIXME: ratelimit */
256 VLOG_DBG("can't forward to bad port %d\n", out_port);
259 /* Takes ownership of 'buffer' and transmits it to 'out_port' on 'dp'.
262 dp_output_port(struct datapath *dp, struct buffer *buffer,
263 int in_port, int out_port)
267 if (out_port == OFPP_FLOOD) {
268 flood(dp, buffer, in_port);
269 } else if (out_port == OFPP_CONTROLLER) {
270 dp_output_control(dp, buffer, in_port, fwd_save_buffer(buffer), 0,
273 output_packet(dp, buffer, out_port);
277 /* Takes ownership of 'buffer' and transmits it to 'dp''s controller. If
278 * 'buffer_id' != -1, then only the first 64 bytes of 'buffer' are sent;
279 * otherwise, all of 'buffer' is sent. 'reason' indicates why 'buffer' is
280 * being sent. 'max_len' sets the maximum number of bytes that the caller wants
281 * to be sent; a value of 0 indicates the entire packet should be sent. */
283 dp_output_control(struct datapath *dp, struct buffer *buffer, int in_port,
284 uint32_t buffer_id, size_t max_len, int reason)
286 struct ofp_packet_in *opi;
289 total_len = buffer->size;
290 if (buffer_id != UINT32_MAX && max_len > buffer->size) {
291 buffer->size = max_len;
294 opi = buffer_push_uninit(buffer, offsetof(struct ofp_packet_in, data));
295 opi->header.version = OFP_VERSION;
296 opi->header.type = OFPT_PACKET_IN;
297 opi->header.length = htons(buffer->size);
298 opi->header.xid = htonl(0);
299 opi->buffer_id = htonl(buffer_id);
300 opi->total_len = htons(total_len);
301 opi->in_port = htons(in_port);
302 opi->reason = reason;
304 controller_send(dp->cc, buffer);
307 static void fill_port_desc(struct datapath *dp, struct sw_port *p,
308 struct ofp_phy_port *desc)
310 desc->port_no = htons(port_no(dp, p));
311 strncpy((char *) desc->name, netdev_get_name(p->netdev),
313 desc->name[sizeof desc->name - 1] = '\0';
314 memcpy(desc->hw_addr, netdev_get_etheraddr(p->netdev), ETH_ADDR_LEN);
315 desc->flags = htonl(p->flags);
316 desc->features = htonl(netdev_get_features(p->netdev));
317 desc->speed = htonl(netdev_get_speed(p->netdev));
321 dp_send_hello(struct datapath *dp)
323 struct buffer *buffer;
324 struct ofp_data_hello *odh;
327 buffer = buffer_new(sizeof *odh);
328 odh = buffer_put_uninit(buffer, sizeof *odh);
329 memset(odh, 0, sizeof *odh);
330 odh->header.version = OFP_VERSION;
331 odh->header.type = OFPT_DATA_HELLO;
332 odh->header.xid = htonl(0);
333 odh->datapath_id = htonll(dp->id);
334 odh->n_exact = htonl(2 * TABLE_HASH_MAX_FLOWS);
335 odh->n_mac_only = htonl(TABLE_MAC_MAX_FLOWS);
336 odh->n_compression = 0; /* Not supported */
337 odh->n_general = htonl(TABLE_LINEAR_MAX_FLOWS);
338 odh->buffer_mb = htonl(UINT32_MAX);
339 odh->n_buffers = htonl(N_PKT_BUFFERS);
340 odh->capabilities = htonl(OFP_SUPPORTED_CAPABILITIES);
341 odh->actions = htonl(OFP_SUPPORTED_ACTIONS);
342 odh->miss_send_len = htons(dp->miss_send_len);
343 LIST_FOR_EACH (p, struct sw_port, node, &dp->port_list) {
344 struct ofp_phy_port *opp = buffer_put_uninit(buffer, sizeof *opp);
345 memset(opp, 0, sizeof *opp);
346 fill_port_desc(dp, p, opp);
348 odh = buffer_at_assert(buffer, 0, sizeof *odh);
349 odh->header.length = htons(buffer->size);
350 controller_send(dp->cc, buffer);
354 dp_update_port_flags(struct datapath *dp, const struct ofp_phy_port *opp)
358 p = &dp->ports[htons(opp->port_no)];
360 /* Make sure the port id hasn't changed since this was sent */
361 if (!p || memcmp(opp->hw_addr, netdev_get_etheraddr(p->netdev),
365 p->flags = htonl(opp->flags);
369 send_port_status(struct sw_port *p, uint8_t status)
371 struct buffer *buffer;
372 struct ofp_port_status *ops;
373 buffer = buffer_new(sizeof *ops);
374 ops = buffer_put_uninit(buffer, sizeof *ops);
375 ops->header.version = OFP_VERSION;
376 ops->header.type = OFPT_PORT_STATUS;
377 ops->header.length = htons(sizeof(*ops));
378 ops->header.xid = htonl(0);
379 ops->reason = status;
380 fill_port_desc(p->dp, p, &ops->desc);
381 controller_send(p->dp->cc, buffer);
385 dp_send_flow_expired(struct datapath *dp, struct sw_flow *flow)
387 struct buffer *buffer;
388 struct ofp_flow_expired *ofe;
389 buffer = buffer_new(sizeof *ofe);
390 ofe = buffer_put_uninit(buffer, sizeof *ofe);
391 ofe->header.version = OFP_VERSION;
392 ofe->header.type = OFPT_FLOW_EXPIRED;
393 ofe->header.length = htons(sizeof(*ofe));
394 ofe->header.xid = htonl(0);
395 flow_fill_match(&ofe->match, &flow->key);
396 ofe->duration = htonl(flow->timeout - flow->max_idle - flow->created);
397 ofe->packet_count = htonll(flow->packet_count);
398 ofe->byte_count = htonll(flow->byte_count);
399 controller_send(dp->cc, buffer);