GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/switchd/ofp13.c Lines: 0 997 0.0 %
Date: 2017-11-07 Branches: 0 640 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: ofp13.c,v 1.43 2017/01/17 09:21:50 rzalamena Exp $	*/
2
3
/*
4
 * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org>
5
 * Copyright (c) 2016 Rafael Zalamena <rzalamena@openbsd.org>
6
 *
7
 * Permission to use, copy, modify, and distribute this software for any
8
 * purpose with or without fee is hereby granted, provided that the above
9
 * copyright notice and this permission notice appear in all copies.
10
 *
11
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
 */
19
20
#include <sys/types.h>
21
#include <sys/queue.h>
22
#include <sys/socket.h>
23
24
#include <net/if.h>
25
#include <net/if_arp.h>
26
#include <net/ofp.h>
27
28
#include <netinet/in.h>
29
#include <netinet/if_ether.h>
30
#include <netinet/tcp.h>
31
#include <netmpls/mpls.h>
32
33
#include <endian.h>
34
#include <stdio.h>
35
#include <stdlib.h>
36
#include <stddef.h>
37
#include <unistd.h>
38
#include <string.h>
39
#include <fcntl.h>
40
#include <imsg.h>
41
#include <event.h>
42
43
#include "switchd.h"
44
#include "ofp_map.h"
45
46
int	 ofp13_echo_request(struct switchd *, struct switch_connection *,
47
	    struct ofp_header *, struct ibuf *);
48
int	 ofp13_validate_features_reply(struct switchd *,
49
	    struct sockaddr_storage *, struct sockaddr_storage *,
50
	    struct ofp_header *, struct ibuf *);
51
int	 ofp13_features_reply(struct switchd *, struct switch_connection *,
52
	    struct ofp_header *, struct ibuf *);
53
int	 ofp13_validate_error(struct switchd *,
54
	    struct sockaddr_storage *, struct sockaddr_storage *,
55
	    struct ofp_header *, struct ibuf *);
56
int	 ofp13_validate_action(struct switchd *, struct ofp_header *,
57
	    struct ibuf *, off_t *, struct ofp_action_header *);
58
int	 ofp13_validate_instruction(struct switchd *, struct ofp_header *,
59
	    struct ibuf *, off_t *, struct ofp_instruction *);
60
int	 ofp13_validate_flow_mod(struct switchd *, struct sockaddr_storage *,
61
	    struct sockaddr_storage *, struct ofp_header *, struct ibuf *);
62
int	 ofp13_validate_oxm_basic(struct ibuf *, off_t, int, uint8_t);
63
int	 ofp13_validate_oxm(struct switchd *, struct ofp_ox_match *,
64
	    struct ofp_header *, struct ibuf *, off_t);
65
int	 ofp13_validate_packet_in(struct switchd *,
66
	    struct sockaddr_storage *, struct sockaddr_storage *,
67
	    struct ofp_header *, struct ibuf *);
68
int	 ofp13_packet_match(struct ibuf *, struct packet *, struct ofp_match *);
69
int	 ofp13_packet_in(struct switchd *, struct switch_connection *,
70
	    struct ofp_header *, struct ibuf *);
71
int	 ofp13_flow_removed(struct switchd *, struct switch_connection *,
72
	    struct ofp_header *, struct ibuf *);
73
int	 ofp13_tableproperties(struct switch_connection *, struct ibuf *,
74
	    off_t, size_t, int);
75
int	 ofp13_multipart_reply(struct switchd *, struct switch_connection *,
76
	    struct ofp_header *, struct ibuf *);
77
int	 ofp13_validate_tableproperty(struct ibuf *, off_t, int);
78
int	 ofp13_multipart_reply_validate(struct switchd *,
79
	    struct sockaddr_storage *, struct sockaddr_storage *,
80
	    struct ofp_header *, struct ibuf *);
81
int	 ofp13_validate_packet_out(struct switchd *,
82
	    struct sockaddr_storage *, struct sockaddr_storage *,
83
	    struct ofp_header *, struct ibuf *);
84
85
struct ofp_multipart *
86
	    ofp13_multipart_request(struct switch_connection *, struct ibuf *,
87
	    uint16_t, uint16_t);
88
int	 ofp13_multipart_request_validate(struct switchd *,
89
	    struct sockaddr_storage *, struct sockaddr_storage *,
90
	    struct ofp_header *, struct ibuf *);
91
92
int	 ofp13_error(struct switchd *, struct switch_connection *,
93
	    struct ofp_header *, struct ibuf *, uint16_t, uint16_t);
94
95
struct ofp_group_mod *
96
	    ofp13_group(struct switch_connection *, struct ibuf *,
97
	    uint32_t, uint16_t, uint8_t);
98
struct ofp_bucket *
99
	    ofp13_bucket(struct ibuf *, uint16_t, uint32_t, uint32_t);
100
101
int	 ofp13_setconfig_validate(struct switchd *,
102
	    struct sockaddr_storage *, struct sockaddr_storage *,
103
	    struct ofp_header *, struct ibuf *);
104
105
int	 ofp13_switchconfigure(struct switchd *, struct switch_connection *);
106
int	 ofp13_getflowtable(struct switch_connection *);
107
108
struct ofp_callback ofp13_callbacks[] = {
109
	{ OFP_T_HELLO,			ofp13_hello, ofp_validate_hello },
110
	{ OFP_T_ERROR,			NULL, ofp13_validate_error },
111
	{ OFP_T_ECHO_REQUEST,		ofp13_echo_request, NULL },
112
	{ OFP_T_ECHO_REPLY,		NULL, NULL },
113
	{ OFP_T_EXPERIMENTER,		NULL, NULL },
114
	{ OFP_T_FEATURES_REQUEST,	NULL, NULL },
115
	{ OFP_T_FEATURES_REPLY,		ofp13_features_reply,
116
					ofp13_validate_features_reply },
117
	{ OFP_T_GET_CONFIG_REQUEST,	NULL, NULL },
118
	{ OFP_T_GET_CONFIG_REPLY,	NULL, NULL },
119
	{ OFP_T_SET_CONFIG,		NULL, ofp13_setconfig_validate },
120
	{ OFP_T_PACKET_IN,		ofp13_packet_in,
121
					ofp13_validate_packet_in },
122
	{ OFP_T_FLOW_REMOVED,		ofp13_flow_removed, NULL },
123
	{ OFP_T_PORT_STATUS,		NULL, NULL },
124
	{ OFP_T_PACKET_OUT,		NULL, ofp13_validate_packet_out },
125
	{ OFP_T_FLOW_MOD,		NULL, ofp13_validate_flow_mod },
126
	{ OFP_T_GROUP_MOD,		NULL, NULL },
127
	{ OFP_T_PORT_MOD,		NULL, NULL },
128
	{ OFP_T_TABLE_MOD,		NULL, NULL },
129
	{ OFP_T_MULTIPART_REQUEST,	NULL,
130
					ofp13_multipart_request_validate },
131
	{ OFP_T_MULTIPART_REPLY,	ofp13_multipart_reply,
132
					ofp13_multipart_reply_validate },
133
	{ OFP_T_BARRIER_REQUEST,	NULL, NULL },
134
	{ OFP_T_BARRIER_REPLY,		NULL, NULL },
135
	{ OFP_T_QUEUE_GET_CONFIG_REQUEST, NULL, NULL },
136
	{ OFP_T_QUEUE_GET_CONFIG_REPLY,	NULL, NULL },
137
	{ OFP_T_ROLE_REQUEST,		NULL, NULL },
138
	{ OFP_T_ROLE_REPLY,		NULL, NULL },
139
	{ OFP_T_GET_ASYNC_REQUEST,	NULL, NULL },
140
	{ OFP_T_GET_ASYNC_REPLY,	NULL, NULL },
141
	{ OFP_T_SET_ASYNC,		NULL, NULL },
142
	{ OFP_T_METER_MOD,		NULL, NULL },
143
};
144
145
int
146
ofp13_validate(struct switchd *sc,
147
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
148
    struct ofp_header *oh, struct ibuf *ibuf)
149
{
150
	uint8_t	type;
151
152
	if (ofp_validate_header(sc, src, dst, oh, OFP_V_1_3) != 0) {
153
		log_debug("\tinvalid header");
154
		return (-1);
155
	}
156
	if (ibuf == NULL) {
157
		/* The response packet buffer is optional */
158
		return (0);
159
	}
160
	type = oh->oh_type;
161
	if (ofp13_callbacks[type].validate != NULL &&
162
	    ofp13_callbacks[type].validate(sc, src, dst, oh, ibuf) != 0) {
163
		log_debug("\tinvalid packet");
164
		return (-1);
165
	}
166
	return (0);
167
}
168
169
int
170
ofp13_validate_oxm_basic(struct ibuf *ibuf, off_t off, int hasmask,
171
    uint8_t type)
172
{
173
	uint8_t		*ui8;
174
	uint16_t	*ui16;
175
	uint32_t	*ui32;
176
	uint64_t	*ui64;
177
	int		 i, len;
178
	char		 hex[8], buf[64], maskbuf[64];
179
180
	switch (type) {
181
	case OFP_XM_T_IN_PORT:
182
	case OFP_XM_T_IN_PHY_PORT:
183
	case OFP_XM_T_MPLS_LABEL:
184
		if (hasmask)
185
			return (-1);
186
		if ((ui32 = ibuf_seek(ibuf, off, sizeof(*ui32))) == NULL)
187
			return (-1);
188
189
		log_debug("\t\t%u", ntohl(*ui32));
190
		break;
191
192
	case OFP_XM_T_META:
193
	case OFP_XM_T_TUNNEL_ID:
194
		len = sizeof(*ui64);
195
		if (hasmask)
196
			len *= 2;
197
198
		if ((ui64 = ibuf_seek(ibuf, off, len)) == NULL)
199
			return (-1);
200
201
		if (hasmask)
202
			log_debug("\t\t%llu mask %#16llx",
203
			    be64toh(*ui64), be64toh(*(ui64 + 1)));
204
		else
205
			log_debug("\t\t%llu", be64toh(*ui64));
206
		break;
207
208
	case OFP_XM_T_ARP_SHA:
209
	case OFP_XM_T_ARP_THA:
210
	case OFP_XM_T_IPV6_ND_SLL:
211
	case OFP_XM_T_IPV6_ND_TLL:
212
		if (hasmask)
213
			return (-1);
214
		if ((ui8 = ibuf_seek(ibuf, off, ETHER_ADDR_LEN)) == NULL)
215
			return (-1);
216
217
		buf[0] = 0;
218
		for (i = 0; i < ETHER_ADDR_LEN; i++) {
219
			snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
220
			strlcat(buf, hex, sizeof(buf));
221
		}
222
223
		log_debug("\t\t%s", buf);
224
		break;
225
226
	case OFP_XM_T_ETH_DST:
227
	case OFP_XM_T_ETH_SRC:
228
		len = ETHER_ADDR_LEN;
229
		if (hasmask)
230
			len *= 2;
231
232
		if ((ui8 = ibuf_seek(ibuf, off, len)) == NULL)
233
			return (-1);
234
235
		buf[0] = 0;
236
		for (i = 0; i < ETHER_ADDR_LEN; i++) {
237
			snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
238
			strlcat(buf, hex, sizeof(buf));
239
		}
240
241
		if (hasmask) {
242
			maskbuf[0] = 0;
243
			for (i = 0; i < ETHER_ADDR_LEN; i++) {
244
				snprintf(hex, sizeof(hex), "%02x", *(ui8 +
245
				    (i + ETHER_ADDR_LEN)));
246
				strlcat(maskbuf, hex, sizeof(maskbuf));
247
			}
248
			log_debug("\t\t%s mask %s", buf, maskbuf);
249
		} else
250
			log_debug("\t\t%s", buf);
251
		break;
252
253
	case OFP_XM_T_ETH_TYPE:
254
		if (hasmask)
255
			return (-1);
256
		len = sizeof(*ui16);
257
		if ((ui16 = ibuf_seek(ibuf, off, len)) == NULL)
258
			return (-1);
259
		log_debug("\t\t0x%04x", ntohs(*ui16));
260
		break;
261
262
	case OFP_XM_T_TCP_SRC:
263
	case OFP_XM_T_TCP_DST:
264
	case OFP_XM_T_UDP_SRC:
265
	case OFP_XM_T_UDP_DST:
266
	case OFP_XM_T_SCTP_SRC:
267
	case OFP_XM_T_SCTP_DST:
268
	case OFP_XM_T_ARP_OP:
269
		if (hasmask)
270
			return (-1);
271
		if ((ui16 = ibuf_seek(ibuf, off, sizeof(*ui16))) == NULL)
272
			return (-1);
273
274
		log_debug("\t\t%d", ntohs(*ui16));
275
		break;
276
277
	case OFP_XM_T_VLAN_VID:
278
	case OFP_XM_T_IPV6_EXTHDR:
279
		len = sizeof(*ui16);
280
		if (hasmask)
281
			len *= 2;
282
283
		if ((ui16 = ibuf_seek(ibuf, off, len)) == NULL)
284
			return (-1);
285
286
		if (type == OFP_XM_T_VLAN_VID) {
287
			/* Remove the VID present bit to display. */
288
			if (hasmask)
289
				log_debug("\t\t%d mask %#04x",
290
				    ntohs(*ui16) & ~OFP_XM_VID_PRESENT,
291
				    ntohs(*(ui16 + 1)));
292
			else
293
				log_debug("\t\t%d",
294
				    ntohs(*ui16) & ~OFP_XM_VID_PRESENT);
295
			break;
296
		}
297
298
		if (hasmask)
299
			log_debug("\t\t%d mask %#04x",
300
			    ntohs(*ui16), ntohs(*(ui16 + 1)));
301
		else
302
			log_debug("\t\t%d", ntohs(*ui16));
303
		break;
304
305
	case OFP_XM_T_IP_DSCP:
306
	case OFP_XM_T_IP_ECN:
307
	case OFP_XM_T_IP_PROTO:
308
	case OFP_XM_T_ICMPV4_TYPE:
309
	case OFP_XM_T_ICMPV4_CODE:
310
	case OFP_XM_T_ICMPV6_TYPE:
311
	case OFP_XM_T_ICMPV6_CODE:
312
	case OFP_XM_T_MPLS_TC:
313
	case OFP_XM_T_MPLS_BOS:
314
		if (hasmask)
315
			return (-1);
316
		if ((ui8 = ibuf_seek(ibuf, off, sizeof(*ui8))) == NULL)
317
			return (-1);
318
319
		log_debug("\t\t%#02x", *ui8);
320
		break;
321
322
	case OFP_XM_T_IPV4_SRC:
323
	case OFP_XM_T_IPV4_DST:
324
	case OFP_XM_T_ARP_SPA:
325
	case OFP_XM_T_ARP_TPA:
326
	case OFP_XM_T_IPV6_FLABEL:
327
		len = sizeof(*ui32);
328
		if (hasmask)
329
			len *= 2;
330
331
		if ((ui32 = ibuf_seek(ibuf, off, len)) == NULL)
332
			return (-1);
333
334
		if (hasmask)
335
			log_debug("\t\t%#08x mask %#08x",
336
			    ntohl(*ui32), ntohl(*(ui32 + 1)));
337
		else
338
			log_debug("\t\t%#08x", ntohl(*ui32));
339
		break;
340
341
	case OFP_XM_T_IPV6_ND_TARGET:
342
		if (hasmask)
343
			return (-1);
344
		if ((ui8 = ibuf_seek(ibuf, off,
345
		    sizeof(struct in6_addr))) == NULL)
346
			return (-1);
347
348
		buf[0] = 0;
349
		for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
350
			snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
351
			strlcat(buf, hex, sizeof(buf));
352
		}
353
354
		log_debug("\t\t%s", buf);
355
		break;
356
357
	case OFP_XM_T_IPV6_SRC:
358
	case OFP_XM_T_IPV6_DST:
359
		len = sizeof(struct in6_addr);
360
		if (hasmask)
361
			len *= 2;
362
363
		if ((ui8 = ibuf_seek(ibuf, off, len)) == NULL)
364
			return (-1);
365
366
		buf[0] = 0;
367
		for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
368
			snprintf(hex, sizeof(hex), "%02x", *(ui8 + i));
369
			strlcat(buf, hex, sizeof(buf));
370
		}
371
372
		if (hasmask) {
373
			maskbuf[0] = 0;
374
			for (i = 0; i < (int)sizeof(struct in6_addr); i++) {
375
				snprintf(hex, sizeof(hex), "%02x", *(ui8 +
376
				    (i + sizeof(struct in6_addr))));
377
				strlcat(maskbuf, hex, sizeof(maskbuf));
378
			}
379
			log_debug("\t\t%s mask %s", buf, maskbuf);
380
		} else
381
			log_debug("\t\t%s", buf);
382
		break;
383
384
	case OFP_XM_T_PBB_ISID:
385
		/* TODO teach me how to read 24 bits and convert to be. */
386
		break;
387
388
	default:
389
		log_debug("\t\tUnknown type");
390
		return (-1);
391
	}
392
393
	return (0);
394
}
395
396
int
397
ofp13_validate_oxm(struct switchd *sc, struct ofp_ox_match *oxm,
398
    struct ofp_header *oh, struct ibuf *ibuf, off_t off)
399
{
400
	uint16_t	 class;
401
	uint8_t		 type;
402
	int		 hasmask;
403
404
	/* match element is always followed by data */
405
	if (oxm->oxm_length == 0)
406
		return (0);
407
408
	type = OFP_OXM_GET_FIELD(oxm);
409
	hasmask = OFP_OXM_GET_HASMASK(oxm);
410
	class = ntohs(oxm->oxm_class);
411
	off += sizeof(*oxm);
412
413
	log_debug("\tox match class %s type %s hasmask %s length %u",
414
	    print_map(class, ofp_oxm_c_map),
415
	    print_map(type, ofp_xm_t_map),
416
	    hasmask ? "yes" : "no",
417
	    oxm->oxm_length);
418
419
	switch (class) {
420
	case OFP_OXM_C_NXM_0:
421
	case OFP_OXM_C_NXM_1:
422
		/* TODO teach me how to read NXM_*. */
423
		break;
424
425
	case OFP_OXM_C_OPENFLOW_BASIC:
426
		return (ofp13_validate_oxm_basic(ibuf, off, hasmask, type));
427
428
	case OFP_OXM_C_OPENFLOW_EXPERIMENTER:
429
		/* Implementation dependent: there is nothing to do here. */
430
		break;
431
432
	default:
433
		return (-1);
434
	}
435
436
	return (0);
437
}
438
439
int
440
ofp13_validate_packet_in(struct switchd *sc,
441
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
442
    struct ofp_header *oh, struct ibuf *ibuf)
443
{
444
	struct ofp_packet_in	*pin;
445
	struct ofp_match	*om;
446
	struct ofp_ox_match	*oxm;
447
	uint8_t			*p;
448
	ssize_t			 len, mlen, plen;
449
	off_t			 moff, off;
450
451
	off = 0;
452
	if ((pin = ibuf_seek(ibuf, off, sizeof(*pin))) == NULL)
453
		return (-1);
454
	log_debug("\tbuffer %s length %u reason %s table %s cookie 0x%#016llx",
455
	    print_map(ntohl(pin->pin_buffer_id), ofp_pktout_map),
456
	    ntohs(pin->pin_total_len),
457
	    print_map(ntohs(pin->pin_reason), ofp_pktin_map),
458
	    print_map(pin->pin_table_id, ofp_table_id_map),
459
	    be64toh(pin->pin_cookie));
460
	off += offsetof(struct ofp_packet_in, pin_match);
461
462
	om = &pin->pin_match;
463
	mlen = ntohs(om->om_length);
464
	log_debug("\tmatch type %s length %zu (padded to %zu)",
465
	    print_map(ntohs(om->om_type), ofp_match_map),
466
	    mlen, OFP_ALIGN(mlen) + ETHER_ALIGN);
467
	mlen -= sizeof(*om);
468
469
	/* current match offset, aligned offset after all matches */
470
	moff = off + sizeof(*om);
471
	off += OFP_ALIGN(mlen) + ETHER_ALIGN;
472
473
	switch (htons(om->om_type)) {
474
	case OFP_MATCH_OXM:
475
		do {
476
			if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
477
				return (-1);
478
			if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
479
				return (-1);
480
			moff += sizeof(*oxm) + oxm->oxm_length;
481
			mlen -= sizeof(*oxm) + oxm->oxm_length;
482
		} while (mlen > 0 && oxm->oxm_length);
483
		break;
484
	case OFP_MATCH_STANDARD:
485
		/* deprecated */
486
		break;
487
	}
488
489
	len = ntohs(pin->pin_total_len);
490
	plen = ibuf_length(ibuf) - off;
491
492
	if (plen < len) {
493
		log_debug("\ttruncated packet %zu < %zu", plen, len);
494
495
		/* Buffered packets can be truncated */
496
		if (pin->pin_buffer_id != OFP_PKTOUT_NO_BUFFER)
497
			len = plen;
498
		else
499
			return (-1);
500
	}
501
	if ((p = ibuf_seek(ibuf, off, len)) == NULL)
502
		return (-1);
503
	if (sc->sc_tap != -1)
504
		(void)write(sc->sc_tap, p, len);
505
506
	return (0);
507
}
508
509
int
510
ofp13_validate_packet_out(struct switchd *sc,
511
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
512
    struct ofp_header *oh, struct ibuf *ibuf)
513
{
514
	struct ofp_packet_out		*pout;
515
	size_t				 len, plen, diff;
516
	off_t				 off, noff;
517
	struct ofp_action_header	*ah;
518
519
	off = 0;
520
	if ((pout = ibuf_seek(ibuf, off, sizeof(*pout))) == NULL) {
521
		log_debug("%s: seek failed: length %zd",
522
		    __func__, ibuf_length(ibuf));
523
		return (-1);
524
	}
525
526
	off += sizeof(*pout);
527
	len = ntohs(pout->pout_actions_len);
528
	log_debug("\tbuffer %s in_port %s actions_len %lu",
529
	    print_map(ntohl(pout->pout_buffer_id), ofp_pktout_map),
530
	    print_map(ntohl(pout->pout_in_port), ofp_port_map), len);
531
532
	while (len > 0) {
533
		if ((ah = ibuf_seek(ibuf, off, sizeof(*ah))) == NULL)
534
			return (-1);
535
536
		noff = off;
537
		ofp13_validate_action(sc, oh, ibuf, &off, ah);
538
539
		diff = off - noff;
540
		/* Loop prevention. */
541
		if (off < noff || diff == 0)
542
			return (-1);
543
544
		len -= diff;
545
	}
546
547
	/* Check for encapsulated packet truncation. */
548
	len = ntohs(oh->oh_length) - off;
549
	plen = ibuf_length(ibuf) - off;
550
551
	if (plen < len) {
552
		log_debug("\ttruncated packet %lu < %lu", plen, len);
553
554
		/* Buffered packets can be truncated */
555
		if (pout->pout_buffer_id != htonl(OFP_PKTOUT_NO_BUFFER))
556
			len = plen;
557
		else
558
			return (-1);
559
	}
560
	if (ibuf_seek(ibuf, off, len) == NULL)
561
		return (-1);
562
563
	return (0);
564
}
565
566
int
567
ofp13_validate_error(struct switchd *sc,
568
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
569
    struct ofp_header *oh, struct ibuf *ibuf)
570
{
571
	struct ofp_error		*err;
572
	off_t				 off;
573
	const char			*code;
574
575
	off = 0;
576
	if ((err = ibuf_seek(ibuf, off, sizeof(*err))) == NULL) {
577
		log_debug("%s: seek failed: length %zd",
578
		    __func__, ibuf_length(ibuf));
579
		return (-1);
580
	}
581
582
	switch (ntohs(err->err_type)) {
583
	case OFP_ERRTYPE_FLOW_MOD_FAILED:
584
		code = print_map(ntohs(err->err_code), ofp_errflowmod_map);
585
		break;
586
	case OFP_ERRTYPE_BAD_MATCH:
587
		code = print_map(ntohs(err->err_code), ofp_errmatch_map);
588
		break;
589
	case OFP_ERRTYPE_BAD_INSTRUCTION:
590
		code = print_map(ntohs(err->err_code), ofp_errinst_map);
591
		break;
592
	case OFP_ERRTYPE_BAD_REQUEST:
593
		code = print_map(ntohs(err->err_code), ofp_errreq_map);
594
		break;
595
	default:
596
		code = NULL;
597
		break;
598
	}
599
600
	log_debug("\terror type %s code %u%s%s",
601
	    print_map(ntohs(err->err_type), ofp_errtype_map),
602
	    ntohs(err->err_code),
603
	    code == NULL ? "" : ": ",
604
	    code == NULL ? "" : code);
605
606
	return (0);
607
}
608
609
int
610
ofp13_input(struct switchd *sc, struct switch_connection *con,
611
    struct ofp_header *oh, struct ibuf *ibuf)
612
{
613
	if (ofp13_validate(sc, &con->con_peer, &con->con_local, oh, ibuf) != 0)
614
		return (-1);
615
616
	if (ofp13_callbacks[oh->oh_type].cb == NULL) {
617
		log_debug("%s: message not supported: %s", __func__,
618
		    print_map(oh->oh_type, ofp_t_map));
619
		return (-1);
620
	}
621
	if (ofp13_callbacks[oh->oh_type].cb(sc, con, oh, ibuf) != 0) {
622
		log_debug("%s: message parsing failed: %s", __func__,
623
		    print_map(oh->oh_type, ofp_t_map));
624
		return (-1);
625
	}
626
627
	return (0);
628
}
629
630
int
631
ofp13_hello(struct switchd *sc, struct switch_connection *con,
632
    struct ofp_header *oh, struct ibuf *ibuf)
633
{
634
	if (switch_add(con) == NULL) {
635
		log_debug("%s: failed to add switch", __func__);
636
		return (-1);
637
	}
638
639
	if (ofp_recv_hello(sc, con, oh, ibuf) == -1)
640
		return (-1);
641
642
	return (ofp_nextstate(sc, con, OFP_STATE_FEATURE_WAIT));
643
}
644
645
int
646
ofp13_echo_request(struct switchd *sc, struct switch_connection *con,
647
    struct ofp_header *oh, struct ibuf *ibuf)
648
{
649
	/* Echo reply */
650
	oh->oh_type = OFP_T_ECHO_REPLY;
651
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, NULL) != 0)
652
		return (-1);
653
	ofp_output(con, oh, NULL);
654
655
	return (0);
656
}
657
658
int
659
ofp13_validate_features_reply(struct switchd *sc,
660
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
661
    struct ofp_header *oh, struct ibuf *ibuf)
662
{
663
	struct ofp_switch_features	*swf;
664
665
	if ((swf = ibuf_seek(ibuf, 0, sizeof(*swf))) == NULL)
666
		return (-1);
667
668
	log_debug("\tdatapath_id %#016llx nbuffers %u ntables %d aux_id %d "
669
	    "capabilities %#08x",
670
	    be64toh(swf->swf_datapath_id), ntohl(swf->swf_nbuffers),
671
	    swf->swf_ntables, swf->swf_aux_id, ntohl(swf->swf_capabilities));
672
	return (0);
673
}
674
675
int
676
ofp13_features_reply(struct switchd *sc, struct switch_connection *con,
677
    struct ofp_header *oh, struct ibuf *ibuf)
678
{
679
	return (ofp_nextstate(sc, con, OFP_STATE_ESTABLISHED));
680
}
681
682
int
683
ofp13_validate_action(struct switchd *sc, struct ofp_header *oh,
684
    struct ibuf *ibuf, off_t *off, struct ofp_action_header *ah)
685
{
686
	struct ofp_action_output	*ao;
687
	struct ofp_action_mpls_ttl	*amt;
688
	struct ofp_action_push		*ap;
689
	struct ofp_action_pop_mpls	*apm;
690
	struct ofp_action_group		*ag;
691
	struct ofp_action_nw_ttl	*ant;
692
	struct ofp_action_set_field	*asf;
693
	struct ofp_action_set_queue	*asq;
694
	struct ofp_ox_match		*oxm;
695
	size_t				 len;
696
	int				 type;
697
	off_t				 moff;
698
699
	type = ntohs(ah->ah_type);
700
	len = ntohs(ah->ah_len);
701
702
	switch (type) {
703
	case OFP_ACTION_OUTPUT:
704
		if (len != sizeof(*ao))
705
			return (-1);
706
		if ((ao = ibuf_seek(ibuf, *off, sizeof(*ao))) == NULL)
707
			return (-1);
708
709
		*off += len;
710
		log_debug("\t\taction %s len %lu port %s max_len %s",
711
		    print_map(type, ofp_action_map), len,
712
		    print_map(ntohl(ao->ao_port), ofp_port_map),
713
		    print_map(ntohs(ao->ao_max_len),
714
		    ofp_controller_maxlen_map));
715
		break;
716
	case OFP_ACTION_SET_MPLS_TTL:
717
		if (len != sizeof(*amt))
718
			return (-1);
719
		if ((amt = ibuf_seek(ibuf, *off, sizeof(*amt))) == NULL)
720
			return (-1);
721
722
		*off += len;
723
		log_debug("\t\taction %s len %lu ttl %d",
724
		    print_map(type, ofp_action_map), len, amt->amt_ttl);
725
		break;
726
	case OFP_ACTION_PUSH_VLAN:
727
	case OFP_ACTION_PUSH_MPLS:
728
	case OFP_ACTION_PUSH_PBB:
729
		if (len != sizeof(*ap))
730
			return (-1);
731
		if ((ap = ibuf_seek(ibuf, *off, sizeof(*ap))) == NULL)
732
			return (-1);
733
734
		*off += len;
735
		log_debug("\t\taction %s len %lu ethertype %#04x",
736
		    print_map(type, ofp_action_map), len,
737
		    ntohs(ap->ap_ethertype));
738
		break;
739
	case OFP_ACTION_POP_MPLS:
740
		if (len != sizeof(*apm))
741
			return (-1);
742
		if ((apm = ibuf_seek(ibuf, *off, sizeof(*apm))) == NULL)
743
			return (-1);
744
745
		*off += len;
746
		log_debug("\t\taction %s len %lu ethertype %#04x",
747
		    print_map(type, ofp_action_map), len,
748
		    ntohs(apm->apm_ethertype));
749
		break;
750
	case OFP_ACTION_SET_QUEUE:
751
		if (len != sizeof(*asq))
752
			return (-1);
753
		if ((asq = ibuf_seek(ibuf, *off, sizeof(*asq))) == NULL)
754
			return (-1);
755
756
		*off += len;
757
		log_debug("\t\taction %s len %lu queue_id %u",
758
		    print_map(type, ofp_action_map), len,
759
		    ntohl(asq->asq_queue_id));
760
		break;
761
	case OFP_ACTION_GROUP:
762
		if (len != sizeof(*ag))
763
			return (-1);
764
		if ((ag = ibuf_seek(ibuf, *off, sizeof(*ag))) == NULL)
765
			return (-1);
766
767
		*off += len;
768
		log_debug("\t\taction %s len %lu group_id %s",
769
		    print_map(type, ofp_action_map), len,
770
		    print_map(ntohl(ag->ag_group_id), ofp_group_id_map));
771
		break;
772
	case OFP_ACTION_SET_NW_TTL:
773
		if (len != sizeof(*ant))
774
			return (-1);
775
		if ((ant = ibuf_seek(ibuf, *off, sizeof(*ant))) == NULL)
776
			return (-1);
777
778
		*off += len;
779
		log_debug("\t\taction %s len %lu ttl %d",
780
		    print_map(type, ofp_action_map), len, ant->ant_ttl);
781
		break;
782
	case OFP_ACTION_SET_FIELD:
783
		if (len < sizeof(*asf))
784
			return (-1);
785
		if ((asf = ibuf_seek(ibuf, *off, sizeof(*asf))) == NULL)
786
			return (-1);
787
788
		moff = *off + sizeof(*asf) - sizeof(asf->asf_field);
789
		*off += len;
790
		log_debug("\t\taction %s len %lu",
791
		    print_map(type, ofp_action_map), len);
792
793
		len -= sizeof(*asf) - sizeof(asf->asf_field);
794
		while (len > 0) {
795
			if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm)))
796
			    == NULL)
797
				return (-1);
798
			if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
799
				return (-1);
800
801
			len -= sizeof(*oxm) + oxm->oxm_length;
802
			moff += sizeof(*oxm) + oxm->oxm_length;
803
		}
804
		break;
805
806
	default:
807
		if (len < sizeof(*ah))
808
			return (-1);
809
810
		/* Generic header without information. */
811
		*off += len;
812
		log_debug("\t\taction %s len %lu",
813
		    print_map(type, ofp_action_map), len);
814
		break;
815
	}
816
817
	return (0);
818
}
819
820
int
821
ofp13_validate_instruction(struct switchd *sc, struct ofp_header *oh,
822
    struct ibuf *ibuf, off_t *off, struct ofp_instruction *i)
823
{
824
	struct ofp_instruction_actions		*ia;
825
	struct ofp_instruction_goto_table	*igt;
826
	struct ofp_instruction_write_metadata	*iwm;
827
	struct ofp_instruction_meter		*im;
828
	struct ofp_action_header		*ah;
829
	int					 type;
830
	size_t					 len;
831
	off_t					 oldoff, diff;
832
833
	type = ntohs(i->i_type);
834
	len = ntohs(i->i_len);
835
836
	switch (type) {
837
	case OFP_INSTRUCTION_T_GOTO_TABLE:
838
		if (len != sizeof(*igt))
839
			return (-1);
840
		if ((igt = ibuf_seek(ibuf, *off, sizeof(*igt))) == NULL)
841
			return (-1);
842
843
		*off += len;
844
		log_debug("\tinstruction %s length %lu table_id %s",
845
		    print_map(type, ofp_instruction_t_map), len,
846
		    print_map(igt->igt_table_id, ofp_table_id_map));
847
		break;
848
	case OFP_INSTRUCTION_T_WRITE_META:
849
		if (len != sizeof(*iwm))
850
			return (-1);
851
		if ((iwm = ibuf_seek(ibuf, *off, sizeof(*iwm))) == NULL)
852
			return (-1);
853
854
		*off += len;
855
		log_debug("\tinstruction %s length %lu "
856
		    "metadata %#016llx mask %#016llx",
857
		    print_map(type, ofp_instruction_t_map), len,
858
		    be64toh(iwm->iwm_metadata),
859
		    be64toh(iwm->iwm_metadata_mask));
860
		break;
861
	case OFP_INSTRUCTION_T_METER:
862
		if (len != sizeof(*im))
863
			return (-1);
864
		if ((im = ibuf_seek(ibuf, *off, sizeof(*im))) == NULL)
865
			return (-1);
866
867
		*off += len;
868
		log_debug("\tinstruction %s length %lu meter_id %d",
869
		    print_map(type, ofp_instruction_t_map), len,
870
		    im->im_meter_id);
871
		break;
872
	case OFP_INSTRUCTION_T_WRITE_ACTIONS:
873
	case OFP_INSTRUCTION_T_CLEAR_ACTIONS:
874
	case OFP_INSTRUCTION_T_APPLY_ACTIONS:
875
		if (len < sizeof(*ia))
876
			return (-1);
877
		if ((ia = ibuf_seek(ibuf, *off, sizeof(*ia))) == NULL)
878
			return (-1);
879
880
		log_debug("\tinstruction %s length %lu",
881
		    print_map(type, ofp_instruction_t_map), len);
882
883
		*off += sizeof(*ia);
884
		len -= sizeof(*ia);
885
		while (len) {
886
			oldoff = *off;
887
			if ((ah = ibuf_seek(ibuf, *off, sizeof(*ah))) == NULL ||
888
			    ofp13_validate_action(sc, oh, ibuf, off, ah) == -1)
889
				return (-1);
890
891
			diff = *off - oldoff;
892
			/* Loop prevention. */
893
			if (*off < oldoff || diff == 0)
894
				break;
895
896
			len -= diff;
897
		}
898
		break;
899
	default:
900
		if (len < sizeof(*i))
901
			return (-1);
902
903
		log_debug("\tinstruction %s length %lu",
904
		    print_map(type, ofp_instruction_t_map), len);
905
		*off += len;
906
		break;
907
	}
908
909
	return (0);
910
}
911
912
int
913
ofp13_validate_flow_mod(struct switchd *sc,
914
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
915
    struct ofp_header *oh, struct ibuf *ibuf)
916
{
917
	struct ofp_flow_mod		*fm;
918
	struct ofp_match		*om;
919
	struct ofp_instruction		*i;
920
	struct ofp_ox_match		*oxm;
921
	off_t				 off, moff, offdiff;
922
	int				 matchlen, matchtype, left;
923
924
	off = 0;
925
	if ((fm = ibuf_seek(ibuf, off, sizeof(*fm))) == NULL)
926
		return (-1);
927
928
	log_debug("\tcommand %s table %s timeout (idle %d hard %d) "
929
	    "priority %d buffer_id %s out_port %s out_group %s "
930
	    "flags %#04x cookie %#016llx mask %#016llx",
931
	    print_map(fm->fm_command, ofp_flowcmd_map),
932
	    print_map(fm->fm_table_id, ofp_table_id_map),
933
	    ntohs(fm->fm_idle_timeout), ntohs(fm->fm_hard_timeout),
934
	    ntohs(fm->fm_priority),
935
	    print_map(ntohl(fm->fm_buffer_id), ofp_pktout_map),
936
	    print_map(ntohl(fm->fm_out_port), ofp_port_map),
937
	    print_map(ntohl(fm->fm_out_group), ofp_group_id_map),
938
	    ntohs(fm->fm_flags), be64toh(fm->fm_cookie),
939
	    be64toh(fm->fm_cookie_mask));
940
941
	off += offsetof(struct ofp_flow_mod, fm_match);
942
943
	om = &fm->fm_match;
944
	matchtype = ntohs(om->om_type);
945
	matchlen = ntohs(om->om_length);
946
947
	moff = off + sizeof(*om);
948
	off += OFP_ALIGN(matchlen);
949
950
	matchlen -= sizeof(*om);
951
	while (matchlen) {
952
		if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL ||
953
		    ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
954
			return (-1);
955
		moff += sizeof(*oxm) + oxm->oxm_length;
956
		matchlen -= sizeof(*oxm) + oxm->oxm_length;
957
	}
958
959
	left = ntohs(oh->oh_length) - off;
960
	moff = off;
961
	while (left) {
962
		if ((i = ibuf_seek(ibuf, moff, sizeof(*i))) == NULL ||
963
		    ofp13_validate_instruction(sc, oh, ibuf, &moff, i) == -1)
964
			return (-1);
965
966
		offdiff = moff - off;
967
		/* Loop prevention. */
968
		if (moff < off || offdiff == 0)
969
			break;
970
971
		left -= offdiff;
972
		off = moff;
973
	}
974
975
	return (0);
976
}
977
978
int
979
ofp13_packet_match(struct ibuf *ibuf, struct packet *pkt, struct ofp_match *om)
980
{
981
	struct ether_header	*eh = pkt->pkt_eh;
982
	size_t			 padsize, startpos, endpos, omlen;
983
984
	if (eh == NULL)
985
		return (-1);
986
987
	startpos = ibuf->wpos;
988
	if (oxm_etheraddr(ibuf, 1, eh->ether_shost, NULL) == -1)
989
		return (-1);
990
	if (oxm_etheraddr(ibuf, 0, eh->ether_dhost, NULL) == -1)
991
		return (-1);
992
	endpos = ibuf->wpos;
993
994
	omlen = sizeof(*om) + (endpos - startpos);
995
	padsize = OFP_ALIGN(omlen) - omlen;
996
997
	om->om_type = htons(OFP_MATCH_OXM);
998
	om->om_length = htons(omlen);
999
	if (padsize && ibuf_advance(ibuf, padsize) == NULL)
1000
		return (-1);
1001
1002
	return (0);
1003
}
1004
1005
int
1006
ofp13_packet_in(struct switchd *sc, struct switch_connection *con,
1007
    struct ofp_header *ih, struct ibuf *ibuf)
1008
{
1009
	struct ofp_packet_in		*pin;
1010
	struct ofp_packet_out		*pout;
1011
	struct ofp_flow_mod		*fm;
1012
	struct ofp_header		*oh;
1013
	struct ofp_match		*om;
1014
	struct ofp_ox_match		*oxm;
1015
	struct packet			 pkt;
1016
	struct ibuf			*obuf = NULL;
1017
	int				 table, ret = -1;
1018
	ssize_t				 len, mlen;
1019
	uint32_t			 srcport = 0, dstport;
1020
	int				 addflow = 0, sendbuffer = 0;
1021
	off_t				 off, moff;
1022
	void				*ptr;
1023
	struct ofp_instruction_actions	*ia;
1024
1025
	if ((pin = ibuf_getdata(ibuf, sizeof(*pin))) == NULL)
1026
		return (-1);
1027
1028
	/* We only handle no matches right now. */
1029
	if (pin->pin_reason != OFP_PKTIN_REASON_NO_MATCH)
1030
		return (-1);
1031
1032
	bzero(&pkt, sizeof(pkt));
1033
	len = ntohs(pin->pin_total_len);
1034
1035
	/* very basic way of getting the source port */
1036
	om = &pin->pin_match;
1037
	mlen = ntohs(om->om_length);
1038
	off = (OFP_ALIGN(mlen) + ETHER_ALIGN) - sizeof(pin->pin_match);
1039
	moff = ibuf_dataoffset(ibuf);
1040
1041
	do {
1042
		if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
1043
			return (-1);
1044
1045
		/* Find IN_PORT */
1046
		switch (ntohs(oxm->oxm_class)) {
1047
		case OFP_OXM_C_OPENFLOW_BASIC:
1048
			switch (OFP_OXM_GET_FIELD(oxm)) {
1049
			case OFP_XM_T_IN_PORT:
1050
				moff += sizeof(*oxm);
1051
				if ((ptr = ibuf_seek(ibuf, moff,
1052
				    sizeof(srcport))) == NULL)
1053
					return (-1);
1054
				srcport = htonl(*(uint32_t *)ptr);
1055
				mlen = 0; /* break loop */
1056
				break;
1057
			default:
1058
				/* ignore unsupported match types */
1059
				break;
1060
			}
1061
		default:
1062
			/* ignore unsupported match classes */
1063
			break;
1064
		}
1065
		moff += sizeof(*oxm) + oxm->oxm_length;
1066
		mlen -= sizeof(*oxm) + oxm->oxm_length;
1067
	} while (mlen > 0 && oxm->oxm_length);
1068
1069
	/* Skip all matches and seek to the packet */
1070
	if (ibuf_getdata(ibuf, off) == NULL)
1071
		return (-1);
1072
1073
	if (packet_input(sc, con->con_switch,
1074
	    srcport, &dstport, ibuf, len, &pkt) == -1 ||
1075
	    (dstport > OFP_PORT_MAX &&
1076
	    dstport != OFP_PORT_LOCAL &&
1077
	    dstport != OFP_PORT_CONTROLLER)) {
1078
		/* fallback to flooding */
1079
		dstport = OFP_PORT_FLOOD;
1080
	} else if (srcport == dstport) {
1081
		/*
1082
		 * silently drop looping packet
1083
		 * (don't use OFP_PORT_INPUT here)
1084
		 */
1085
		dstport = OFP_PORT_ANY;
1086
	} else {
1087
		addflow = 1;
1088
	}
1089
1090
	if ((obuf = ibuf_static()) == NULL)
1091
		goto done;
1092
1093
 again:
1094
	if (addflow) {
1095
		table = ofp13_getflowtable(con);
1096
		if (table > OFP_TABLE_ID_MAX || table < 0) {
1097
			/* This switch doesn't support installing flows. */
1098
			addflow = 0;
1099
			goto again;
1100
		}
1101
1102
		if ((fm = ibuf_advance(obuf, sizeof(*fm))) == NULL)
1103
			goto done;
1104
1105
		oh = &fm->fm_oh;
1106
		fm->fm_cookie = 0; /* XXX should we set a cookie? */
1107
		fm->fm_command = OFP_FLOWCMD_ADD;
1108
		fm->fm_idle_timeout = htons(sc->sc_cache_timeout);
1109
		fm->fm_hard_timeout = 0; /* permanent */
1110
		fm->fm_priority = 0;
1111
		fm->fm_buffer_id = pin->pin_buffer_id;
1112
		fm->fm_table_id = table;
1113
		fm->fm_flags = htons(OFP_FLOWFLAG_SEND_FLOW_REMOVED);
1114
		if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER))
1115
			sendbuffer = 1;
1116
1117
		/* Write flow matches to create an entry. */
1118
		if (ofp13_packet_match(obuf, &pkt, &fm->fm_match) == -1)
1119
			goto done;
1120
1121
		/*
1122
		 * Write the instruction action header and add the output
1123
		 * action.
1124
		 */
1125
		if ((ia = ibuf_advance(obuf, sizeof(*ia))) == NULL ||
1126
		    action_output(obuf, dstport,
1127
		    OFP_CONTROLLER_MAXLEN_NO_BUFFER) == -1)
1128
			goto done;
1129
1130
		ia->ia_type = htons(OFP_INSTRUCTION_T_APPLY_ACTIONS);
1131
		ia->ia_len = htons(sizeof(*ia) +
1132
		    sizeof(struct ofp_action_output));
1133
	} else {
1134
		if ((pout = ibuf_advance(obuf, sizeof(*pout))) == NULL)
1135
			goto done;
1136
1137
		oh = &pout->pout_oh;
1138
		pout->pout_buffer_id = pin->pin_buffer_id;
1139
		pout->pout_in_port = htonl(srcport);
1140
		pout->pout_actions_len =
1141
		    htons(sizeof(struct ofp_action_output));
1142
1143
		if (action_output(obuf, dstport,
1144
		    OFP_CONTROLLER_MAXLEN_NO_BUFFER) == -1)
1145
			goto done;
1146
1147
		/* Add optional packet payload */
1148
		if (pin->pin_buffer_id == htonl(OFP_PKTOUT_NO_BUFFER) &&
1149
		    imsg_add(obuf, pkt.pkt_buf, pkt.pkt_len) == -1)
1150
			goto done;
1151
	}
1152
1153
	/* Set output header */
1154
	oh->oh_version = OFP_V_1_3;
1155
	oh->oh_length = htons(ibuf_length(obuf));
1156
	oh->oh_type = addflow ? OFP_T_FLOW_MOD : OFP_T_PACKET_OUT;
1157
	oh->oh_xid = htonl(con->con_xidnxt++);
1158
1159
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, obuf) != 0)
1160
		goto done;
1161
1162
	ofp_output(con, NULL, obuf);
1163
1164
	if (sendbuffer) {
1165
		ibuf_release(obuf);
1166
1167
		/* loop to output the packet again */
1168
		addflow = sendbuffer = 0;
1169
		if ((obuf = ibuf_static()) == NULL)
1170
			goto done;
1171
		goto again;
1172
	}
1173
1174
	ret = 0;
1175
 done:
1176
	ibuf_release(obuf);
1177
	return (ret);
1178
}
1179
1180
int
1181
ofp13_flow_removed(struct switchd *sc, struct switch_connection *con,
1182
    struct ofp_header *ih, struct ibuf *ibuf)
1183
{
1184
	struct ofp_flow_removed		*fr;
1185
1186
	if ((fr = ibuf_getdata(ibuf, sizeof(*fr))) == NULL)
1187
		return (-1);
1188
1189
	log_debug("cookie %#016llx priority %d reason %s table_id %s "
1190
	    "duration(%u sec, %u nsec) timeout idle %d hard %d "
1191
	    "packet %llu byte %llu",
1192
	    be64toh(fr->fr_cookie), ntohs(fr->fr_priority),
1193
	    print_map(fr->fr_reason, ofp_flowrem_reason_map),
1194
	    print_map(fr->fr_table_id, ofp_table_id_map),
1195
	    ntohl(fr->fr_duration_sec), ntohl(fr->fr_duration_nsec),
1196
	    ntohs(fr->fr_idle_timeout), ntohs(fr->fr_hard_timeout),
1197
	    be64toh(fr->fr_packet_count), be64toh(fr->fr_byte_count));
1198
1199
	return (0);
1200
}
1201
1202
int
1203
ofp13_tableproperties(struct switch_connection *con, struct ibuf *ibuf,
1204
    off_t off, size_t total, int new)
1205
{
1206
	struct ofp_table_features		*tf;
1207
	struct ofp_table_feature_property	*tp;
1208
	struct ofp_instruction			*i;
1209
	struct ofp_action_header		*ah;
1210
	struct ofp_ox_match			*oxm;
1211
	struct switch_table			*st;
1212
	uint8_t					*next_table;
1213
	int					 remaining, type, length;
1214
	int					 hlen, padsize;
1215
	int					 class, dtype, dlen;
1216
1217
	/*
1218
	 * This is a new table features reply, free our previous tables
1219
	 * to get the updated ones.
1220
	 */
1221
	if (new)
1222
		switch_freetables(con);
1223
1224
 next_table:
1225
	if ((tf = ibuf_seek(ibuf, off, sizeof(*tf))) == NULL)
1226
		return (-1);
1227
1228
	hlen = htons(tf->tf_length);
1229
	total -= hlen;
1230
	remaining = hlen - sizeof(*tf);
1231
	off += sizeof(*tf);
1232
1233
	st = switch_tablelookup(con, tf->tf_tableid);
1234
	if (st == NULL) {
1235
		st = switch_newtable(con, tf->tf_tableid);
1236
		if (st == NULL)
1237
			return (-1);
1238
	}
1239
1240
	st->st_maxentries = ntohl(tf->tf_max_entries);
1241
1242
 next_table_property:
1243
	if ((tp = ibuf_seek(ibuf, off, sizeof(*tp))) == NULL) {
1244
		switch_deltable(con, st);
1245
		return (-1);
1246
	}
1247
1248
	type = ntohs(tp->tp_type);
1249
	length = ntohs(tp->tp_length);
1250
1251
	/* Calculate the padding. */
1252
	padsize = OFP_ALIGN(length) - length;
1253
	remaining -= OFP_ALIGN(length);
1254
	length -= sizeof(*tp);
1255
	off += sizeof(*tp);
1256
1257
	switch (type) {
1258
	case OFP_TABLE_FEATPROP_INSTRUCTION:
1259
	case OFP_TABLE_FEATPROP_INSTRUCTION_MISS:
1260
		if (type == OFP_TABLE_FEATPROP_INSTRUCTION)
1261
			st->st_instructions = 0;
1262
		else
1263
			st->st_instructionsmiss = 0;
1264
1265
		while (length) {
1266
			if ((i = ibuf_seek(ibuf, off, sizeof(*i))) == NULL) {
1267
				switch_deltable(con, st);
1268
				return (-1);
1269
			}
1270
1271
			dtype = ntohs(i->i_type);
1272
			dlen = ntohs(i->i_len);
1273
			if (type == OFP_TABLE_FEATPROP_INSTRUCTION)
1274
				st->st_instructions |= 1ULL << dtype;
1275
			else
1276
				st->st_instructionsmiss |= 1ULL << dtype;
1277
1278
			if (dtype == OFP_INSTRUCTION_T_EXPERIMENTER) {
1279
				length -= dlen;
1280
				off += dlen;
1281
			} else {
1282
				length -= sizeof(*i);
1283
				off += sizeof(*i);
1284
			}
1285
		}
1286
		break;
1287
1288
	case OFP_TABLE_FEATPROP_NEXT_TABLES:
1289
	case OFP_TABLE_FEATPROP_NEXT_TABLES_MISS:
1290
		if (type == OFP_TABLE_FEATPROP_NEXT_TABLES)
1291
			memset(st->st_nexttable, 0, sizeof(st->st_nexttable));
1292
		else
1293
			memset(st->st_nexttablemiss, 0,
1294
			    sizeof(st->st_nexttablemiss));
1295
1296
		while (length) {
1297
			if ((next_table = ibuf_seek(ibuf, off,
1298
			    sizeof(*next_table))) == NULL) {
1299
				switch_deltable(con, st);
1300
				return (-1);
1301
			}
1302
1303
			if (type == OFP_TABLE_FEATPROP_NEXT_TABLES)
1304
				st->st_nexttable[(*next_table) / 64] |=
1305
				    1ULL << ((*next_table) % 64);
1306
			else
1307
				st->st_nexttablemiss[(*next_table) / 64] |=
1308
				    1ULL << ((*next_table) % 64);
1309
1310
			length -= sizeof(*next_table);
1311
			off += sizeof(*next_table);
1312
		}
1313
		break;
1314
1315
	case OFP_TABLE_FEATPROP_WRITE_ACTIONS:
1316
	case OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS:
1317
	case OFP_TABLE_FEATPROP_APPLY_ACTIONS:
1318
	case OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS:
1319
		if (type == OFP_TABLE_FEATPROP_WRITE_ACTIONS ||
1320
		    type == OFP_TABLE_FEATPROP_APPLY_ACTIONS)
1321
			st->st_actions = 0;
1322
		else
1323
			st->st_actionsmiss = 0;
1324
1325
		while (length) {
1326
			/*
1327
			 * NOTE the OpenFlow 1.3.5 specs says that we only
1328
			 * get 4 bytes here instead of the full action header.
1329
			 */
1330
			if ((ah = ibuf_seek(ibuf, off, 4)) == NULL) {
1331
				switch_deltable(con, st);
1332
				return (-1);
1333
			}
1334
1335
			dtype = ntohs(ah->ah_type);
1336
			dlen = ntohs(ah->ah_len);
1337
			if (type == OFP_TABLE_FEATPROP_WRITE_ACTIONS ||
1338
			    type == OFP_TABLE_FEATPROP_APPLY_ACTIONS)
1339
				st->st_actions |= 1ULL << dtype;
1340
			else
1341
				st->st_actionsmiss |= 1ULL << dtype;
1342
1343
			if (dtype == OFP_ACTION_EXPERIMENTER) {
1344
				length -= dlen;
1345
				off += dlen;
1346
			} else {
1347
				length -= 4;
1348
				off += 4;
1349
			}
1350
		}
1351
		break;
1352
1353
	case OFP_TABLE_FEATPROP_MATCH:
1354
	case OFP_TABLE_FEATPROP_WILDCARDS:
1355
	case OFP_TABLE_FEATPROP_WRITE_SETFIELD:
1356
	case OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS:
1357
	case OFP_TABLE_FEATPROP_APPLY_SETFIELD:
1358
	case OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS:
1359
		if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD ||
1360
		    type == OFP_TABLE_FEATPROP_APPLY_SETFIELD)
1361
			st->st_setfield = 0;
1362
		else if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS ||
1363
			type == OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS)
1364
			st->st_setfieldmiss = 0;
1365
		else if (type == OFP_TABLE_FEATPROP_MATCH)
1366
			st->st_match = 0;
1367
		else
1368
			st->st_wildcard = 0;
1369
1370
		while (length) {
1371
			if ((oxm = ibuf_seek(ibuf, off,
1372
			    sizeof(*oxm))) == NULL) {
1373
				switch_deltable(con, st);
1374
				return (-1);
1375
			}
1376
1377
			class = ntohs(oxm->oxm_class);
1378
			if (class != OFP_OXM_C_OPENFLOW_BASIC) {
1379
				if (class == OFP_OXM_C_OPENFLOW_EXPERIMENTER) {
1380
					length -= sizeof(*oxm) + 4;
1381
					off += sizeof(*oxm) + 4;
1382
				} else {
1383
					length -= sizeof(*oxm);
1384
					off += sizeof(*oxm);
1385
				}
1386
				continue;
1387
			}
1388
1389
			dtype = OFP_OXM_GET_FIELD(oxm);
1390
			if (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD ||
1391
			    type == OFP_TABLE_FEATPROP_APPLY_SETFIELD)
1392
				st->st_setfield |= 1ULL << dtype;
1393
			else if
1394
			    (type == OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS ||
1395
			    type == OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS)
1396
				st->st_setfieldmiss |= 1ULL << dtype;
1397
			else if (type == OFP_TABLE_FEATPROP_MATCH)
1398
				st->st_match |= 1ULL << dtype;
1399
			else
1400
				st->st_wildcard |= 1ULL << dtype;
1401
1402
			length -= sizeof(*oxm);
1403
			off += sizeof(*oxm);
1404
		}
1405
		break;
1406
1407
	case OFP_TABLE_FEATPROP_EXPERIMENTER:
1408
	case OFP_TABLE_FEATPROP_EXPERIMENTER_MISS:
1409
		off += length;
1410
		break;
1411
1412
	default:
1413
		log_debug("Unsupported table property %d", type);
1414
		return (-1);
1415
	}
1416
1417
	if (padsize)
1418
		off += padsize;
1419
	if (remaining > 0)
1420
		goto next_table_property;
1421
	if (total > 0)
1422
		goto next_table;
1423
1424
	return (0);
1425
}
1426
1427
int
1428
ofp13_multipart_reply(struct switchd *sc, struct switch_connection *con,
1429
    struct ofp_header *oh, struct ibuf *ibuf)
1430
{
1431
	struct ofp_multipart		*mp;
1432
	int				 type, flags, more, new = 0;
1433
	int				 remaining;
1434
	off_t				 off;
1435
1436
	off = 0;
1437
	if ((mp = ibuf_seek(ibuf, 0, sizeof(*mp))) == NULL)
1438
		return (-1);
1439
1440
	type = ntohs(mp->mp_type);
1441
	flags = ntohs(mp->mp_flags);
1442
	remaining = ntohs(oh->oh_length) - sizeof(*mp);
1443
	off += sizeof(*mp);
1444
1445
	more = (flags & OFP_MP_FLAG_REPLY_MORE) == OFP_MP_FLAG_REPLY_MORE;
1446
	/* Signalize new requests. */
1447
	if (ofp_multipart_lookup(con, oh->oh_xid) == NULL)
1448
		new = 1;
1449
1450
	if (more) {
1451
		if (ofp_multipart_add(con, oh->oh_xid, type) == -1) {
1452
			ofp13_error(sc, con, oh, ibuf,
1453
			    OFP_ERRTYPE_BAD_REQUEST,
1454
			    OFP_ERRREQ_MULTIPART_OVERFLOW);
1455
			ofp_multipart_del(con, oh->oh_xid);
1456
			return (0);
1457
		}
1458
1459
		/*
1460
		 * We don't need to concatenate with other messages,
1461
		 * because the specification says that switches don't
1462
		 * break objects. We should only need this if our parser
1463
		 * requires the whole data before hand, but then we have
1464
		 * better ways to achieve the same thing.
1465
		 */
1466
	} else
1467
		ofp_multipart_del(con, oh->oh_xid);
1468
1469
	switch (type) {
1470
	case OFP_MP_T_TABLE_FEATURES:
1471
		if (ofp13_tableproperties(con, ibuf, off, remaining, new))
1472
			return (-1);
1473
1474
		/* We finished receiving tables, configure the switch. */
1475
		if (more == 0)
1476
			return (ofp13_switchconfigure(sc, con));
1477
		break;
1478
	}
1479
1480
	return (0);
1481
}
1482
1483
int
1484
ofp13_validate_tableproperty(struct ibuf *ibuf, off_t off, int remaining)
1485
{
1486
	struct ofp_table_features		*tf;
1487
	struct ofp_table_feature_property	*tp;
1488
	struct ofp_instruction			*i;
1489
	struct ofp_action_header		*ah;
1490
	struct ofp_ox_match			*oxm;
1491
	uint8_t					*nexttable;
1492
	int					 hlen, htype, tplen;
1493
	int					 type, length, class;
1494
	int					 padsize;
1495
1496
 next_table:
1497
	if ((tf = ibuf_seek(ibuf, off, sizeof(*tf))) == NULL)
1498
		return (-1);
1499
1500
	hlen = ntohs(tf->tf_length);
1501
	log_debug("\t\ttable features length %d tableid %s "
1502
	    " name \"%s\" metadata match %#016llx write %#016llx "
1503
	    "config %u max_entries %u",
1504
	    hlen, print_map(tf->tf_tableid, ofp_table_id_map), tf->tf_name,
1505
	    be64toh(tf->tf_metadata_match),
1506
	    be64toh(tf->tf_metadata_write), ntohl(tf->tf_config),
1507
	    ntohl(tf->tf_max_entries));
1508
1509
	off += sizeof(*tf);
1510
	remaining -= sizeof(*tf);
1511
	hlen -= sizeof(*tf);
1512
1513
 next_property:
1514
	if ((tp = ibuf_seek(ibuf, off, sizeof(*tp))) == NULL)
1515
		return (-1);
1516
1517
	off += sizeof(*tp);
1518
	htype = ntohs(tp->tp_type);
1519
	tplen = ntohs(tp->tp_length);
1520
	padsize = OFP_ALIGN(tplen) - tplen;
1521
	remaining -= tplen;
1522
	hlen -= tplen;
1523
1524
	/* Don't count the header bytes for payload. */
1525
	tplen -= sizeof(*tp);
1526
1527
	log_debug("\t\t%s (length %d):",
1528
	    print_map(htype, ofp_table_featprop_map), tplen);
1529
	if (tplen <= 0)
1530
		goto empty_table;
1531
1532
	switch (htype) {
1533
	case OFP_TABLE_FEATPROP_INSTRUCTION:
1534
	case OFP_TABLE_FEATPROP_INSTRUCTION_MISS:
1535
		while (tplen > 0) {
1536
			if ((i = ibuf_seek(ibuf, off, sizeof(*i))) == NULL)
1537
				return (-1);
1538
1539
			type = ntohs(i->i_type);
1540
			length = ntohs(i->i_len);
1541
			if (type == OFP_INSTRUCTION_T_EXPERIMENTER) {
1542
				tplen -= length;
1543
				off += length;
1544
			} else {
1545
				tplen -= sizeof(*i);
1546
				off += sizeof(*i);
1547
			}
1548
1549
			log_debug("\t\t\ttype %s length %d",
1550
			    print_map(type, ofp_instruction_t_map), length);
1551
		}
1552
		break;
1553
1554
	case OFP_TABLE_FEATPROP_NEXT_TABLES:
1555
	case OFP_TABLE_FEATPROP_NEXT_TABLES_MISS:
1556
		while (tplen > 0) {
1557
			if ((nexttable = ibuf_seek(ibuf, off,
1558
			    sizeof(*nexttable))) == NULL)
1559
				return (-1);
1560
1561
			log_debug("\t\t\t%d", *nexttable);
1562
1563
			off += sizeof(*nexttable);
1564
			tplen -= sizeof(*nexttable);
1565
		}
1566
		break;
1567
1568
	case OFP_TABLE_FEATPROP_WRITE_ACTIONS:
1569
	case OFP_TABLE_FEATPROP_WRITE_ACTIONS_MISS:
1570
	case OFP_TABLE_FEATPROP_APPLY_ACTIONS:
1571
	case OFP_TABLE_FEATPROP_APPLY_ACTIONS_MISS:
1572
		while (tplen > 0) {
1573
			/* NOTE: we read the action header without the pad. */
1574
			if ((ah = ibuf_seek(ibuf, off, 4)) == NULL)
1575
				return (-1);
1576
1577
			type = ntohs(ah->ah_type);
1578
			length = ntohs(ah->ah_len);
1579
			log_debug("\t\t\taction %s length %d",
1580
			    print_map(type, ofp_action_map), length);
1581
			if (type == OFP_ACTION_EXPERIMENTER) {
1582
				tplen -= length;
1583
				off += length;
1584
			} else {
1585
				tplen -= 4;
1586
				off += 4;
1587
			}
1588
		}
1589
		break;
1590
1591
	case OFP_TABLE_FEATPROP_MATCH:
1592
	case OFP_TABLE_FEATPROP_WILDCARDS:
1593
	case OFP_TABLE_FEATPROP_WRITE_SETFIELD:
1594
	case OFP_TABLE_FEATPROP_WRITE_SETFIELD_MISS:
1595
	case OFP_TABLE_FEATPROP_APPLY_SETFIELD:
1596
	case OFP_TABLE_FEATPROP_APPLY_SETFIELD_MISS:
1597
		while (tplen > 0) {
1598
			if ((oxm = ibuf_seek(ibuf, off, sizeof(*oxm))) == NULL)
1599
				return (-1);
1600
1601
			class = ntohs(oxm->oxm_class);
1602
			type = OFP_OXM_GET_FIELD(oxm);
1603
			length = oxm->oxm_length;
1604
			if (class == OFP_OXM_C_OPENFLOW_EXPERIMENTER) {
1605
				off += sizeof(*oxm) + 4;
1606
				tplen -= sizeof(*oxm) + 4;
1607
			} else {
1608
				off += sizeof(*oxm);
1609
				tplen -= sizeof(*oxm);
1610
			}
1611
1612
			log_debug("\t\t\tclass %s type %s length %d",
1613
			    print_map(class, ofp_oxm_c_map),
1614
			    print_map(type, ofp_xm_t_map), length);
1615
		}
1616
		break;
1617
1618
	case OFP_TABLE_FEATPROP_EXPERIMENTER:
1619
	case OFP_TABLE_FEATPROP_EXPERIMENTER_MISS:
1620
		off += tplen;
1621
		break;
1622
1623
	default:
1624
		return (-1);
1625
	}
1626
1627
 empty_table:
1628
	if (padsize) {
1629
		off += padsize;
1630
		remaining -= padsize;
1631
		hlen -= padsize;
1632
	}
1633
	if (hlen > 0)
1634
		goto next_property;
1635
	if (remaining > 0)
1636
		goto next_table;
1637
1638
	return (0);
1639
}
1640
1641
int
1642
ofp13_multipart_reply_validate(struct switchd *sc,
1643
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
1644
    struct ofp_header *oh, struct ibuf *ibuf)
1645
{
1646
	struct ofp_multipart		*mp;
1647
	struct ofp_flow_stats		*fs;
1648
	struct ofp_desc			*d;
1649
	struct ofp_match		*om;
1650
	struct ofp_ox_match		*oxm;
1651
	struct ofp_instruction		*oi;
1652
	int				 mptype, mpflags, hlen;
1653
	int				 remaining, matchlen, matchtype;
1654
	int				 ilen, padsize;
1655
	off_t				 off, moff, offdiff;
1656
1657
	remaining = ntohs(oh->oh_length);
1658
1659
	off = 0;
1660
	if ((mp = ibuf_seek(ibuf, off, sizeof(*mp))) == NULL)
1661
		return (-1);
1662
1663
	mptype = ntohs(mp->mp_type);
1664
	mpflags = ntohs(mp->mp_flags);
1665
	log_debug("\ttype %s flags %#04x",
1666
	    print_map(mptype, ofp_mp_t_map), mpflags);
1667
1668
	off += sizeof(*mp);
1669
	remaining -= sizeof(*mp);
1670
	if (remaining == 0) {
1671
		log_debug("\tempty reply");
1672
		return (0);
1673
	}
1674
1675
	switch (mptype) {
1676
	case OFP_MP_T_DESC:
1677
		if ((d = ibuf_seek(ibuf, off, sizeof(*d))) == NULL)
1678
			return (-1);
1679
1680
		off += sizeof(*d);
1681
		remaining -= sizeof(*d);
1682
		log_debug("\tmfr_desc \"%s\" hw_desc \"%s\" sw_desc \"%s\" "
1683
		    "serial_num \"%s\" dp_desc \"%s\"",
1684
		    d->d_mfr_desc, d->d_hw_desc, d->d_sw_desc,
1685
		    d->d_serial_num, d->d_dp_desc);
1686
		break;
1687
1688
	case OFP_MP_T_FLOW:
1689
 read_next_flow:
1690
		if ((fs = ibuf_seek(ibuf, off, sizeof(*fs))) == NULL)
1691
			return (-1);
1692
1693
		hlen = ntohs(fs->fs_length);
1694
		remaining -= hlen;
1695
		moff = off + sizeof(*fs);
1696
		off += hlen;
1697
1698
		log_debug("\tflow length %d table_id %s duration sec %u "
1699
		    "nsec %u prio %d timeout idle %d hard %d flags %#04x "
1700
		    "cookie %#016llx packet count %llu byte count %llu",
1701
		    hlen, print_map(fs->fs_table_id, ofp_table_id_map),
1702
		    ntohl(fs->fs_duration_sec), ntohl(fs->fs_duration_nsec),
1703
		    ntohs(fs->fs_priority), ntohs(fs->fs_idle_timeout),
1704
		    ntohs(fs->fs_hard_timeout), ntohs(fs->fs_flags),
1705
		    be64toh(fs->fs_cookie), be64toh(fs->fs_packet_count),
1706
		    be64toh(fs->fs_byte_count));
1707
1708
		om = &fs->fs_match;
1709
		matchtype = ntohs(om->om_type);
1710
		matchlen = ntohs(om->om_length);
1711
		padsize = OFP_ALIGN(matchlen) - matchlen;
1712
		ilen = hlen -
1713
		    ((sizeof(*fs) - sizeof(*om)) + matchlen + padsize);
1714
1715
		/* We don't know how to parse anything else yet. */
1716
		if (matchtype != OFP_MATCH_OXM)
1717
			break;
1718
1719
		matchlen -= sizeof(*om);
1720
		while (matchlen) {
1721
			if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
1722
				return (-1);
1723
			if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
1724
				return (-1);
1725
			moff += sizeof(*oxm) + oxm->oxm_length;
1726
			matchlen -= sizeof(*oxm) + oxm->oxm_length;
1727
		}
1728
1729
		moff += padsize;
1730
1731
		while (ilen) {
1732
			offdiff = moff;
1733
			if ((oi = ibuf_seek(ibuf, moff, sizeof(*oi))) == NULL ||
1734
			    ofp13_validate_instruction(sc, oh, ibuf,
1735
			    &moff, oi) == -1)
1736
				return (-1);
1737
			/* Avoid loops. */
1738
			if ((moff - offdiff) == 0)
1739
				return (-1);
1740
1741
			ilen -= moff - offdiff;
1742
		}
1743
1744
		if (remaining)
1745
			goto read_next_flow;
1746
		break;
1747
1748
	case OFP_MP_T_AGGREGATE:
1749
	case OFP_MP_T_TABLE:
1750
	case OFP_MP_T_PORT_STATS:
1751
	case OFP_MP_T_QUEUE:
1752
	case OFP_MP_T_GROUP:
1753
	case OFP_MP_T_GROUP_DESC:
1754
	case OFP_MP_T_GROUP_FEATURES:
1755
	case OFP_MP_T_METER:
1756
	case OFP_MP_T_METER_CONFIG:
1757
	case OFP_MP_T_METER_FEATURES:
1758
		break;
1759
1760
	case OFP_MP_T_TABLE_FEATURES:
1761
		if (ofp13_validate_tableproperty(ibuf, off, remaining))
1762
			return (-1);
1763
		break;
1764
1765
	case OFP_MP_T_PORT_DESC:
1766
	case OFP_MP_T_EXPERIMENTER:
1767
		break;
1768
1769
	default:
1770
		return (-1);
1771
	}
1772
1773
	return (0);
1774
}
1775
1776
/* Don't forget to update mp->mp_oh.oh_length */
1777
struct ofp_multipart *
1778
ofp13_multipart_request(struct switch_connection *con, struct ibuf *ibuf,
1779
    uint16_t type, uint16_t flags)
1780
{
1781
	struct ofp_multipart		*mp;
1782
	struct ofp_header		*oh;
1783
1784
	if ((mp = ibuf_advance(ibuf, sizeof(*mp))) == NULL)
1785
		return (NULL);
1786
1787
	oh = &mp->mp_oh;
1788
	oh->oh_version = OFP_V_1_3;
1789
	oh->oh_type = OFP_T_MULTIPART_REQUEST;
1790
	oh->oh_xid = htonl(con->con_xidnxt++);
1791
	mp->mp_type = htons(type);
1792
	mp->mp_flags = htons(flags);
1793
	return (mp);
1794
}
1795
1796
int
1797
ofp13_multipart_request_validate(struct switchd *sc,
1798
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
1799
    struct ofp_header *oh, struct ibuf *ibuf)
1800
{
1801
	struct ofp_multipart		*mp;
1802
	struct ofp_match		*om;
1803
	struct ofp_flow_stats_request	*fsr;
1804
	struct ofp_ox_match		*oxm;
1805
	off_t				 off, moff;
1806
	int				 type, flags, totallen;
1807
	int				 matchlen, matchtype;
1808
1809
	off = 0;
1810
	if ((mp = ibuf_seek(ibuf, off, sizeof(*mp))) == NULL)
1811
		return (-1);
1812
1813
	type = ntohs(mp->mp_type);
1814
	flags = ntohs(mp->mp_flags);
1815
	log_debug("\ttype %s flags %#04x",
1816
	    print_map(type, ofp_mp_t_map), flags);
1817
1818
	totallen = ntohs(oh->oh_length);
1819
	off += sizeof(*mp);
1820
1821
	switch (type) {
1822
	case OFP_MP_T_DESC:
1823
		/* This type doesn't use a payload. */
1824
		if (totallen != sizeof(*mp))
1825
			return (-1);
1826
		break;
1827
1828
	case OFP_MP_T_FLOW:
1829
		if ((fsr = ibuf_seek(ibuf, off, sizeof(*fsr))) == NULL)
1830
			return (-1);
1831
1832
		om = &fsr->fsr_match;
1833
		matchtype = ntohs(om->om_type);
1834
		matchlen = ntohs(om->om_length);
1835
		log_debug("\ttable_id %s out_port %s out_group %s "
1836
		    "cookie %#016llx mask %#016llx match type %s length %d "
1837
		    "(padded to %d)",
1838
		    print_map(fsr->fsr_table_id, ofp_table_id_map),
1839
		    print_map(ntohl(fsr->fsr_out_port), ofp_port_map),
1840
		    print_map(ntohl(fsr->fsr_out_group), ofp_group_id_map),
1841
		    be64toh(fsr->fsr_cookie), be64toh(fsr->fsr_cookie_mask),
1842
		    print_map(matchtype, ofp_match_map), matchlen,
1843
		    OFP_ALIGN(matchlen));
1844
1845
		/* Get the first OXM byte offset. */
1846
		moff = off + sizeof(*fsr);
1847
1848
		/* Don't count the header bytes. */
1849
		matchlen -= sizeof(*om);
1850
1851
		/* We don't know how to parse anything else yet. */
1852
		if (matchtype != OFP_MATCH_OXM)
1853
			break;
1854
1855
		while (matchlen) {
1856
			if ((oxm = ibuf_seek(ibuf, moff, sizeof(*oxm))) == NULL)
1857
				return (-1);
1858
			if (ofp13_validate_oxm(sc, oxm, oh, ibuf, moff) == -1)
1859
				return (-1);
1860
			moff += sizeof(*oxm) + oxm->oxm_length;
1861
			matchlen -= sizeof(*oxm) + oxm->oxm_length;
1862
		}
1863
		break;
1864
1865
	case OFP_MP_T_AGGREGATE:
1866
	case OFP_MP_T_TABLE:
1867
	case OFP_MP_T_PORT_STATS:
1868
	case OFP_MP_T_QUEUE:
1869
	case OFP_MP_T_GROUP:
1870
	case OFP_MP_T_GROUP_DESC:
1871
	case OFP_MP_T_GROUP_FEATURES:
1872
	case OFP_MP_T_METER:
1873
	case OFP_MP_T_METER_CONFIG:
1874
	case OFP_MP_T_METER_FEATURES:
1875
		break;
1876
1877
	case OFP_MP_T_TABLE_FEATURES:
1878
		if (totallen == sizeof(*mp)) {
1879
			log_debug("\tempty table properties request");
1880
			break;
1881
		}
1882
		break;
1883
1884
	case OFP_MP_T_PORT_DESC:
1885
	case OFP_MP_T_EXPERIMENTER:
1886
		break;
1887
1888
	default:
1889
		return (-1);
1890
	}
1891
1892
	return (0);
1893
}
1894
1895
int
1896
ofp13_desc(struct switchd *sc, struct switch_connection *con)
1897
{
1898
	struct ofp_header		*oh;
1899
	struct ofp_multipart		*mp;
1900
	struct ibuf			*ibuf;
1901
	int				 rv = -1;
1902
1903
	if ((ibuf = ibuf_static()) == NULL)
1904
		return (-1);
1905
1906
	if ((mp = ofp13_multipart_request(con, ibuf, OFP_MP_T_DESC, 0)) == NULL)
1907
		goto done;
1908
1909
	oh = &mp->mp_oh;
1910
	oh->oh_length = htons(sizeof(*mp));
1911
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
1912
		goto done;
1913
1914
	rv = ofp_output(con, NULL, ibuf);
1915
1916
 done:
1917
	ibuf_free(ibuf);
1918
	return (rv);
1919
}
1920
1921
int
1922
ofp13_flow_stats(struct switchd *sc, struct switch_connection *con,
1923
    uint32_t out_port, uint32_t out_group, uint8_t table_id)
1924
{
1925
	struct ofp_header		*oh;
1926
	struct ofp_multipart		*mp;
1927
	struct ofp_flow_stats_request	*fsr;
1928
	struct ofp_match		*om;
1929
	struct ibuf			*ibuf;
1930
	int				 padsize, rv = -1;
1931
1932
	if ((ibuf = ibuf_static()) == NULL)
1933
		return (-1);
1934
1935
	if ((mp = ofp13_multipart_request(con, ibuf, OFP_MP_T_FLOW, 0)) == NULL)
1936
		goto done;
1937
	if ((fsr = ibuf_advance(ibuf, sizeof(*fsr))) == NULL)
1938
		goto done;
1939
1940
	oh = &mp->mp_oh;
1941
	fsr->fsr_table_id = table_id;
1942
	fsr->fsr_out_port = htonl(out_port);
1943
	fsr->fsr_out_group = htonl(out_group);
1944
1945
	om = &fsr->fsr_match;
1946
	om->om_type = htons(OFP_MATCH_OXM);
1947
	om->om_length = htons(sizeof(*om));
1948
	padsize = OFP_ALIGN(sizeof(*om)) - sizeof(*om);
1949
	if (padsize && ibuf_advance(ibuf, padsize) == NULL)
1950
		goto done;
1951
1952
	oh->oh_length = htons(ibuf_length(ibuf));
1953
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
1954
		goto done;
1955
1956
	rv = ofp_output(con, NULL, ibuf);
1957
1958
 done:
1959
	ibuf_free(ibuf);
1960
	return (rv);
1961
}
1962
1963
int
1964
ofp13_table_features(struct switchd *sc, struct switch_connection *con,
1965
    uint8_t tableid)
1966
{
1967
	struct ofp_header		*oh;
1968
	struct ofp_multipart		*mp;
1969
	struct ibuf			*ibuf;
1970
	int				 rv = -1;
1971
1972
	if ((ibuf = ibuf_static()) == NULL)
1973
		return (-1);
1974
1975
	if ((mp = ofp13_multipart_request(con, ibuf,
1976
	    OFP_MP_T_TABLE_FEATURES, 0)) == NULL)
1977
		goto done;
1978
1979
	oh = &mp->mp_oh;
1980
	oh->oh_length = htons(sizeof(*mp));
1981
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
1982
		goto done;
1983
1984
	rv = ofp_output(con, NULL, ibuf);
1985
1986
 done:
1987
	ibuf_free(ibuf);
1988
	return (rv);
1989
}
1990
1991
int
1992
ofp13_error(struct switchd *sc, struct switch_connection *con,
1993
    struct ofp_header *oh, struct ibuf *ibuf, uint16_t type, uint16_t code)
1994
{
1995
	struct ibuf		*obuf;
1996
	struct ofp_error	*err;
1997
	struct ofp_header	*header;
1998
	int			 dlen, rv = -1;
1999
2000
	if ((obuf = ibuf_static()) == NULL ||
2001
	    (err = ibuf_advance(obuf, sizeof(*err))) == NULL)
2002
		goto done;
2003
2004
	header = &err->err_oh;
2005
	err->err_type = htons(type);
2006
	err->err_code = htons(code);
2007
2008
	/* Copy the first message bytes for the error payload. */
2009
	dlen = ibuf_size(ibuf);
2010
	if (dlen > OFP_ERRDATA_MAX)
2011
		dlen = OFP_ERRDATA_MAX;
2012
	if (ibuf_add(obuf, ibuf_seek(ibuf, 0, dlen), dlen) == -1)
2013
		goto done;
2014
2015
	header->oh_version = OFP_V_1_3;
2016
	header->oh_type = OFP_T_ERROR;
2017
	header->oh_length = htons(ibuf_length(obuf));
2018
	header->oh_xid = oh->oh_xid;
2019
	if (ofp13_validate(sc, &con->con_peer, &con->con_local, header,
2020
	    obuf) == -1)
2021
		goto done;
2022
2023
	rv = ofp_output(con, NULL, obuf);
2024
2025
 done:
2026
	ibuf_free(obuf);
2027
	return (rv);
2028
}
2029
2030
/*
2031
 * The valid commands for groups are:
2032
 * OFP_GROUPCMD_{ADD,MODIFY,DELETE}
2033
 *
2034
 * The valid type for groups are:
2035
 * OFP_GROUP_T_{ALL,SELECT,INDIRECT,FAST_FAILOVER}
2036
 *
2037
 * You have to update the gm->gm_oh.oh_length = htons(ibuf_length(ibuf));
2038
 */
2039
struct ofp_group_mod *
2040
ofp13_group(struct switch_connection *con, struct ibuf *ibuf,
2041
    uint32_t gid, uint16_t cmd, uint8_t type)
2042
{
2043
	struct ofp_group_mod		*gm;
2044
	struct ofp_header		*oh;
2045
2046
	if ((gm = ibuf_advance(ibuf, sizeof(*gm))) == NULL)
2047
		return (NULL);
2048
2049
	oh = &gm->gm_oh;
2050
	oh->oh_version = OFP_V_1_3;
2051
	oh->oh_type = OFP_T_GROUP_MOD;
2052
	oh->oh_xid = htonl(con->con_xidnxt++);
2053
	gm->gm_command = htons(cmd);
2054
	gm->gm_type = type;
2055
	gm->gm_group_id = htonl(gid);
2056
	return (gm);
2057
}
2058
2059
/* Remember to update b->b_len. */
2060
struct ofp_bucket *
2061
ofp13_bucket(struct ibuf *ibuf, uint16_t weight, uint32_t watchport,
2062
    uint32_t watchgroup)
2063
{
2064
	struct ofp_bucket		*b;
2065
2066
	if ((b = ibuf_advance(ibuf, sizeof(*b))) == NULL)
2067
		return (NULL);
2068
2069
	b->b_weight = htons(weight);
2070
	b->b_watch_port = htonl(watchport);
2071
	b->b_watch_group = htonl(watchgroup);
2072
	return (b);
2073
}
2074
2075
int
2076
ofp13_setconfig_validate(struct switchd *sc,
2077
    struct sockaddr_storage *src, struct sockaddr_storage *dst,
2078
    struct ofp_header *oh, struct ibuf *ibuf)
2079
{
2080
	struct ofp_switch_config	*cfg;
2081
2082
	if ((cfg = ibuf_seek(ibuf, 0, sizeof(*cfg))) == NULL)
2083
		return (-1);
2084
2085
	log_debug("\tflags %#04x miss_send_len %s",
2086
	    ntohs(cfg->cfg_flags), print_map(ntohs(cfg->cfg_miss_send_len),
2087
	    ofp_controller_maxlen_map));
2088
	return (0);
2089
}
2090
2091
int
2092
ofp13_setconfig(struct switchd *sc, struct switch_connection *con,
2093
     uint16_t flags, uint16_t misslen)
2094
{
2095
	struct ibuf			*ibuf;
2096
	struct ofp_switch_config	*cfg;
2097
	struct ofp_header		*oh;
2098
	int				 rv = -1;
2099
2100
	if ((ibuf = ibuf_static()) == NULL ||
2101
	    (cfg = ibuf_advance(ibuf, sizeof(*cfg))) == NULL)
2102
		goto done;
2103
2104
	cfg->cfg_flags = htons(flags);
2105
	cfg->cfg_miss_send_len = htons(misslen);
2106
2107
	oh = &cfg->cfg_oh;
2108
	oh->oh_version = OFP_V_1_3;
2109
	oh->oh_type = OFP_T_SET_CONFIG;
2110
	oh->oh_length = htons(ibuf_length(ibuf));
2111
	oh->oh_xid = htonl(con->con_xidnxt++);
2112
	if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
2113
		goto done;
2114
2115
	rv = ofp_output(con, NULL, ibuf);
2116
2117
 done:
2118
	ibuf_free(ibuf);
2119
	return (rv);
2120
}
2121
2122
/*
2123
 * Flow modification message.
2124
 *
2125
 * After the flow-mod header we have N OXM filters to match packets, when
2126
 * you finish adding them you must update match header:
2127
 * fm_match.om_length = sizeof(fm_match) + OXM length.
2128
 *
2129
 * Then you must add flow instructions and update the OFP header length:
2130
 * fm_oh.oh_length =
2131
 *     sizeof(*fm) + (fm_match.om_len - sizeof(fm_match)) + instructionslen.
2132
 * or
2133
 * fm_oh.oh_length = ibuf_length(ibuf).
2134
 *
2135
 * Note on match payload:
2136
 * After adding all matches and before starting to insert instructions you
2137
 * must add the mandatory padding to fm_match. You can calculate the padding
2138
 * size with this formula:
2139
 * padsize = OFP_ALIGN(fm_match.om_length) - fm_match.om_length;
2140
 *
2141
 * Note on Table-miss:
2142
 * To make a table miss you need to set priority 0 and don't add any
2143
 * matches, just instructions.
2144
 */
2145
struct ofp_flow_mod *
2146
ofp13_flowmod(struct switch_connection *con, struct ibuf *ibuf,
2147
    uint8_t cmd, uint8_t table, uint16_t idleto, uint16_t hardto,
2148
    uint16_t prio)
2149
{
2150
	struct ofp_flow_mod		*fm;
2151
2152
	if ((fm = ibuf_advance(ibuf, sizeof(*fm))) == NULL)
2153
		return (NULL);
2154
2155
	fm->fm_oh.oh_version = OFP_V_1_3;
2156
	fm->fm_oh.oh_type = OFP_T_FLOW_MOD;
2157
	fm->fm_oh.oh_length = htons(sizeof(*fm));
2158
	fm->fm_oh.oh_xid = htonl(con->con_xidnxt++);
2159
2160
	fm->fm_command = cmd;
2161
	fm->fm_buffer_id = htonl(OFP_PKTOUT_NO_BUFFER);
2162
	fm->fm_flags = htons(OFP_FLOWFLAG_SEND_FLOW_REMOVED);
2163
2164
	fm->fm_match.om_type = htons(OFP_MATCH_OXM);
2165
	fm->fm_match.om_length = htons(sizeof(fm->fm_match));
2166
2167
	return (fm);
2168
}
2169
2170
int
2171
ofp13_tablemiss_sendctrl(struct switchd *sc, struct switch_connection *con,
2172
    uint8_t table)
2173
{
2174
	struct oflowmod_ctx	 ctx;
2175
	struct ibuf		*ibuf;
2176
	int			 ret;
2177
2178
	if ((ibuf = oflowmod_open(&ctx, con, NULL, OFP_V_1_3)) == NULL)
2179
		goto err;
2180
2181
	if (oflowmod_iopen(&ctx) == -1)
2182
		goto err;
2183
2184
	/* Update header */
2185
	ctx.ctx_fm->fm_table_id = table;
2186
2187
	if (oflowmod_instruction(&ctx,
2188
	    OFP_INSTRUCTION_T_APPLY_ACTIONS) == -1)
2189
		goto err;
2190
	if (action_output(ibuf, OFP_PORT_CONTROLLER,
2191
	    OFP_CONTROLLER_MAXLEN_MAX) == -1)
2192
		goto err;
2193
2194
	if (oflowmod_iclose(&ctx) == -1)
2195
		goto err;
2196
	if (oflowmod_close(&ctx) == -1)
2197
		goto err;
2198
2199
	if (ofp13_validate(sc, &con->con_local, &con->con_peer,
2200
	    &ctx.ctx_fm->fm_oh, ibuf) != 0)
2201
		goto err;
2202
2203
	ret = ofp_output(con, NULL, ibuf);
2204
	ibuf_release(ibuf);
2205
2206
	return (ret);
2207
2208
 err:
2209
	(void)oflowmod_err(&ctx, __func__, __LINE__);
2210
	return (-1);
2211
}
2212
2213
int
2214
ofp13_switchconfigure(struct switchd *sc, struct switch_connection *con)
2215
{
2216
	struct switch_table		*st;
2217
2218
	/* Look for a table with 'apply' and 'output' support for miss. */
2219
	TAILQ_FOREACH(st, &con->con_stlist, st_entry) {
2220
		if ((st->st_instructionsmiss &
2221
		    (1ULL << OFP_INSTRUCTION_T_APPLY_ACTIONS)) == 0)
2222
			continue;
2223
		if ((st->st_actionsmiss & (1ULL << OFP_ACTION_OUTPUT)) == 0)
2224
			continue;
2225
2226
		break;
2227
	}
2228
	if (st == NULL) {
2229
		log_warn("No apply output for this switch");
2230
		return (-1);
2231
	}
2232
2233
	/* Install the flow to receive packets from the switch. */
2234
	return (ofp13_tablemiss_sendctrl(sc, con, st->st_table));
2235
}
2236
2237
int
2238
ofp13_getflowtable(struct switch_connection *con)
2239
{
2240
	struct switch_table		*st;
2241
2242
	/* Look for a table with 'apply' and 'output' support. */
2243
	TAILQ_FOREACH(st, &con->con_stlist, st_entry) {
2244
		if ((st->st_instructions &
2245
		    (1ULL << OFP_INSTRUCTION_T_APPLY_ACTIONS)) == 0)
2246
			continue;
2247
		if ((st->st_actions & (1ULL << OFP_ACTION_OUTPUT)) == 0)
2248
			continue;
2249
2250
		break;
2251
	}
2252
	if (st == NULL)
2253
		return (-1);
2254
2255
	return (st->st_table);
2256
}