summaryrefslogtreecommitdiff
path: root/include/openvswitch/ofp-packet.h
blob: 77128d829b6de5983652cc5393d29f778e5aecd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/*
 * Copyright (c) 2008-2017 Nicira, Inc.
 *
 * 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.
 */

#ifndef OPENVSWITCH_OFP_PACKET_H
#define OPENVSWITCH_OFP_PACKET_H 1

#include "openflow/openflow.h"
#include "openflow/nicira-ext.h"
#include "openvswitch/match.h"
#include "openvswitch/ofp-protocol.h"
#include "openvswitch/type-props.h"
#include "openvswitch/uuid.h"

#ifdef __cplusplus
extern "C" {
#endif

struct vl_mff_map;
struct ofputil_table_map;

/* Packet-in format.
 *
 * For any given OpenFlow version, Open vSwitch supports multiple formats for
 * "packet-in" messages.  The default is always the standard format for the
 * OpenFlow version in question, but the Open vSwitch extension request
 * NXT_SET_PACKET_IN_FORMAT can be used to set an alternative format.
 *
 * From OVS v1.1 to OVS v2.5, this request was only honored for OpenFlow 1.0.
 * Requests to set format NXPIF_NXT_PACKET_IN were accepted for OF1.1+ but they
 * had no effect.  (Requests to set formats other than NXPIF_STANDARD or
 * NXPIF_NXT_PACKET_IN were rejected with OFPBRC_EPERM.)
 *
 * From OVS v2.6 onward, this request is honored for all OpenFlow versions.
 */
enum ofputil_packet_in_format {
    OFPUTIL_PACKET_IN_STD = 0,  /* OFPT_PACKET_IN for this OpenFlow version. */
    OFPUTIL_PACKET_IN_NXT = 1,  /* NXT_PACKET_IN (since OVS v1.1). */
    OFPUTIL_PACKET_IN_NXT2 = 2, /* NXT_PACKET_IN2 (since OVS v2.6). */
};

int ofputil_packet_in_format_from_string(const char *);
const char *ofputil_packet_in_format_to_string(enum ofputil_packet_in_format);
struct ofpbuf *ofputil_encode_set_packet_in_format(
    enum ofp_version, enum ofputil_packet_in_format);
enum ofperr ofputil_decode_set_packet_in_format(
    const struct ofp_header *, enum ofputil_packet_in_format *);

/* Abstract packet-in message.
 *
 * This omits the 'total_len' and 'buffer_id' fields, which we handle
 * differently for encoding and decoding.*/
struct ofputil_packet_in {
    /* Packet data and metadata.
     *
     * On encoding, the full packet should be supplied, but depending on its
     * other parameters ofputil_encode_packet_in() might send only the first
     * part of the packet.
     *
     * On decoding, the 'len' bytes in 'packet' might only be the first part of
     * the original packet.  ofputil_decode_packet_in() reports the full
     * original length of the packet using its 'total_len' output parameter. */
    void *packet;               /* The packet. */
    size_t packet_len;          /* Length of 'packet' in bytes. */

    /* Input port and other metadata for packet. */
    struct match flow_metadata;

    /* Reason that the packet-in is being sent. */
    enum ofp_packet_in_reason reason;    /* One of OFPR_*. */

    /* Information about the OpenFlow flow that triggered the packet-in.
     *
     * A packet-in triggered by a flow table miss has no associated flow.  In
     * that case, 'cookie' is UINT64_MAX. */
    uint8_t table_id;                    /* OpenFlow table ID. */
    ovs_be64 cookie;                     /* Flow's cookie. */

    /* Arbitrary user-provided data. */
    uint8_t *userdata;
    size_t userdata_len;
};

void ofputil_packet_in_destroy(struct ofputil_packet_in *);

enum ofperr ofputil_decode_packet_in(const struct ofp_header *, bool loose,
                                     const struct tun_table *,
                                     const struct vl_mff_map *,
                                     struct ofputil_packet_in *,
                                     size_t *total_len, uint32_t *buffer_id,
                                     struct ofpbuf *continuation);

struct ofpbuf *ofputil_encode_resume(const struct ofputil_packet_in *pin,
                                     const struct ofpbuf *continuation,
                                     enum ofputil_protocol);

enum { OFPUTIL_PACKET_IN_REASON_BUFSIZE = INT_STRLEN(int) + 1 };
const char *ofputil_packet_in_reason_to_string(enum ofp_packet_in_reason,
                                               char *reasonbuf,
                                               size_t bufsize);
bool ofputil_packet_in_reason_from_string(const char *,
                                          enum ofp_packet_in_reason *);

/* A packet-in message, including continuation data.  The format of
 * continuation data is subject to change and thus it is supposed to be opaque
 * to any process other than ovs-vswitchd.  Therefore, only ovs-vswitchd should
 * use ofputil_packet_in_private and the functions that operate on it. */
struct ofputil_packet_in_private {
    struct ofputil_packet_in base;

    /* NXCPT_BRIDGE. */
    struct uuid bridge;

    /* NXCPT_STACK. */
    uint8_t *stack;
    size_t stack_size;

    /* NXCPT_MIRRORS. */
    uint32_t mirrors;

    /* NXCPT_CONNTRACKED. */
    bool conntracked;

    /* NXCPT_ACTIONS. */
    struct ofpact *actions;
    size_t actions_len;

    /* NXCPT_ACTION_SET. */
    struct ofpact *action_set;
    size_t action_set_len;

    /* NXCPT_ODP_PORT. */
    odp_port_t odp_port;
};

struct ofpbuf *ofputil_encode_packet_in_private(
    const struct ofputil_packet_in_private *,
    enum ofputil_protocol protocol,
    enum ofputil_packet_in_format);

enum ofperr ofputil_decode_packet_in_private(
    const struct ofp_header *, bool loose,
    const struct tun_table *,
    const struct vl_mff_map *,
    struct ofputil_packet_in_private *,
    size_t *total_len, uint32_t *buffer_id);

void ofputil_packet_in_private_format(
    struct ds *, const struct ofputil_packet_in_private *,
    size_t total_len, uint32_t buffer_id,
    const struct ofputil_port_map *,
    const struct ofputil_table_map *, int verbosity);

void ofputil_packet_in_private_destroy(struct ofputil_packet_in_private *);

/* Abstract packet-out message.
 *
 * ofputil_decode_packet_out() will ensure that 'in_port' is a physical port
 * (OFPP_MAX or less) or one of OFPP_LOCAL, OFPP_NONE, or OFPP_CONTROLLER. */
struct ofputil_packet_out {
    const void *packet;         /* Packet data, if buffer_id == UINT32_MAX. */
    size_t packet_len;          /* Length of packet data in bytes. */
    uint32_t buffer_id;         /* Buffer id or UINT32_MAX if no buffer. */
    struct match flow_metadata; /* Packet's input port and other metadata. */
    struct ofpact *ofpacts;     /* Actions. */
    size_t ofpacts_len;         /* Size of ofpacts in bytes. */
};

enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
                                      const struct ofp_header *,
                                      const struct tun_table *,
                                      struct ofpbuf *ofpacts);
struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *,
                                         enum ofputil_protocol protocol);

void ofputil_packet_out_format(struct ds *, const struct ofputil_packet_out *,
                               const struct ofputil_port_map *,
                               const struct ofputil_table_map *,
                               int verbosity);

char *parse_ofp_packet_out_str(struct ofputil_packet_out *, const char *,
                               const struct ofputil_port_map *,
                               const struct ofputil_table_map *,
                               enum ofputil_protocol *usable_protocols)
    OVS_WARN_UNUSED_RESULT;

#ifdef __cplusplus
}
#endif

#endif  /* ofp-packet.h */